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.
@@ -1,6 +1,6 @@
1
1
  const reWhiteSpace$1 = /^[\S]+( [\S]+)*$/gi;
2
+ let cspEnabled = false;
2
3
  const xpathCache$1 = {};
3
- let multiElementReferenceMode = false;
4
4
  let relativeXPathCache = new Map();
5
5
  let modifiedElementAttributes$1 = [];
6
6
  let mutationObserver;
@@ -59,7 +59,7 @@ const getTextContent = (targetElement) => {
59
59
  const getFilteredText = (element) => {
60
60
  return element?.childNodes[0]?.nodeValue || "";
61
61
  };
62
- const getCountOfXPath = (xpath, element, docmt) => {
62
+ const getCountOfXPath = (xpath, element, docmt, multiElementReferenceMode = false) => {
63
63
  try {
64
64
  let count;
65
65
  // Check if result is cached
@@ -73,7 +73,23 @@ const getCountOfXPath = (xpath, element, docmt) => {
73
73
  count = owner.evaluate(`count(${xpath})`, docmt, null, XPathResult.NUMBER_TYPE, null).numberValue;
74
74
  xpathCache$1[xpath] = count;
75
75
  }
76
- if (multiElementReferenceMode && Array.isArray(element)) ;
76
+ if (multiElementReferenceMode && Array.isArray(element)) {
77
+ if (count > 1) {
78
+ const elementsFromXpath = getElementFromXpath(xpath, docmt, true);
79
+ let nodex, matchedCount = 0;
80
+ if (elementsFromXpath instanceof XPathResult) {
81
+ while ((nodex = elementsFromXpath?.iterateNext())) {
82
+ if (element.includes(nodex)) {
83
+ matchedCount += 1;
84
+ if (matchedCount === 2)
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ if (matchedCount !== 2)
90
+ return 0;
91
+ }
92
+ }
77
93
  else {
78
94
  // Short-circuit if we only need to match one element
79
95
  if (count === 1) {
@@ -212,12 +228,6 @@ const getRelationship = (a, b) => {
212
228
  ? "self"
213
229
  : "";
214
230
  };
215
- const findRoot = (node) => {
216
- while (node && node.parentNode) {
217
- node = node.parentNode;
218
- }
219
- return node;
220
- };
221
231
  const isSvg = (element) => {
222
232
  return element instanceof SVGElement;
223
233
  };
@@ -855,12 +865,12 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget) => {
855
865
  }
856
866
  return xpaths1;
857
867
  };
858
- function parseXml(xmlStr) {
868
+ const parseXml = (xmlStr) => {
859
869
  if (window.DOMParser) {
860
870
  return new window.DOMParser().parseFromString(xmlStr, "text/xml");
861
871
  }
862
872
  return null;
863
- }
873
+ };
864
874
  const normalizeXPath = (xpath) => {
865
875
  // Replace text() = "value" or text()='value'
866
876
  xpath = xpath.replace(/text\(\)\s*=\s*(['"])(.*?)\1/g, "normalize-space(.)=$1$2$1");
@@ -908,6 +918,7 @@ const xpathUtils = {
908
918
  startObserver,
909
919
  stopObserver,
910
920
  modifiedElementAttributes: modifiedElementAttributes$1,
921
+ cspEnabled
911
922
  };
912
923
 
913
924
  let xpathData$1 = [];
@@ -1617,7 +1628,7 @@ const parseDOM = (element, doc, isIndex, isTarget) => {
1617
1628
  const len = xpathData$1.length;
1618
1629
  for (let i = 0; i < len; i++) {
1619
1630
  let xpth = xpathData$1[i].value;
1620
- xpth = xpth.replace(tag, "*");
1631
+ xpth = "//*" + xpth.substring(xpth.indexOf("//") + 2 + tag.length);
1621
1632
  const count = getCountOfXPath(xpth, element, docmt);
1622
1633
  if (count === 1) {
1623
1634
  xpathData$1.push({
@@ -1652,13 +1663,12 @@ const xpath = {
1652
1663
  let xpathDataWithIndex = [];
1653
1664
  let xpathData = [];
1654
1665
  const reWhiteSpace = /^[\S]+( [\S]+)*$/gi;
1655
- const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex) => {
1666
+ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex, multiElementReferenceMode = false) => {
1656
1667
  // debugger;
1657
1668
  const par1 = element1.parentElement;
1658
1669
  const par2 = element2.parentElement;
1659
1670
  let rel_xpath = [];
1660
1671
  let tempElement;
1661
- findRoot(element1);
1662
1672
  let finalXpaths = [];
1663
1673
  if (isIndex) {
1664
1674
  if (xpathDataWithIndex.length) {
@@ -1678,14 +1688,14 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1678
1688
  // both are same
1679
1689
  if (element1.isSameNode(element2)) {
1680
1690
  // rel_xpath = xpath1 + "/self::" + element1.tagName;
1681
- rel_xpath = getXpathRelationExpression(element1, element2, "self", xpaths1, xpaths2, isIndex);
1691
+ rel_xpath = getXpathRelationExpression(element1, element2, "self", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1682
1692
  if (rel_xpath)
1683
1693
  finalXpaths = finalXpaths.concat(rel_xpath);
1684
1694
  }
1685
1695
  // parent
1686
1696
  tempElement = element1.parentElement;
1687
1697
  if (tempElement === element2) {
1688
- rel_xpath = getXpathRelationExpression(element1, element2, "parent", xpaths1, xpaths2, isIndex);
1698
+ rel_xpath = getXpathRelationExpression(element1, element2, "parent", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1689
1699
  if (rel_xpath)
1690
1700
  finalXpaths = finalXpaths.concat(rel_xpath);
1691
1701
  }
@@ -1693,7 +1703,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1693
1703
  tempElement = element1.parentElement;
1694
1704
  while (tempElement !== null) {
1695
1705
  if (tempElement === element2) {
1696
- rel_xpath = getXpathRelationExpression(element1, element2, "ancestor", xpaths1, xpaths2, isIndex);
1706
+ rel_xpath = getXpathRelationExpression(element1, element2, "ancestor", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1697
1707
  if (rel_xpath) {
1698
1708
  finalXpaths = finalXpaths.concat(rel_xpath);
1699
1709
  break;
@@ -1705,7 +1715,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1705
1715
  tempElement = element1;
1706
1716
  do {
1707
1717
  if (tempElement === element2) {
1708
- rel_xpath = getXpathRelationExpression(element1, element2, "ancestor-or-self", xpaths1, xpaths2, isIndex);
1718
+ rel_xpath = getXpathRelationExpression(element1, element2, "ancestor-or-self", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1709
1719
  if (rel_xpath) {
1710
1720
  finalXpaths = finalXpaths.concat(rel_xpath);
1711
1721
  break;
@@ -1717,7 +1727,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1717
1727
  if (par1?.isSameNode(par2)) {
1718
1728
  for (let m = element1.nextElementSibling; m != null; m = m.nextElementSibling) {
1719
1729
  if (m != null && m.isSameNode(element2)) {
1720
- rel_xpath = getXpathRelationExpression(element1, element2, "following-sibling", xpaths1, xpaths2, isIndex);
1730
+ rel_xpath = getXpathRelationExpression(element1, element2, "following-sibling", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1721
1731
  if (rel_xpath) {
1722
1732
  finalXpaths = finalXpaths.concat(rel_xpath);
1723
1733
  break;
@@ -1726,7 +1736,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1726
1736
  }
1727
1737
  for (let n = element1.previousElementSibling; n != null; n = n.previousElementSibling) {
1728
1738
  if (n != null && n.isSameNode(element2)) {
1729
- rel_xpath = getXpathRelationExpression(element1, element2, "preceding-sibling", xpaths1, xpaths2, isIndex);
1739
+ rel_xpath = getXpathRelationExpression(element1, element2, "preceding-sibling", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1730
1740
  if (rel_xpath) {
1731
1741
  finalXpaths = finalXpaths.concat(rel_xpath);
1732
1742
  break;
@@ -1738,7 +1748,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1738
1748
  if (element1?.children?.length) {
1739
1749
  for (let m = element1.children[0]; m !== null; m = m?.nextElementSibling) {
1740
1750
  if (m === element2) {
1741
- rel_xpath = getXpathRelationExpression(element1, element2, "child", xpaths1, xpaths2, isIndex);
1751
+ rel_xpath = getXpathRelationExpression(element1, element2, "child", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1742
1752
  if (rel_xpath) {
1743
1753
  finalXpaths = finalXpaths.concat(rel_xpath);
1744
1754
  break;
@@ -1749,18 +1759,18 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1749
1759
  // following
1750
1760
  const relation = element1.compareDocumentPosition(element2);
1751
1761
  if (relation === 2) {
1752
- rel_xpath = getXpathRelationExpression(element1, element2, "preceding", xpaths1, xpaths2, isIndex);
1762
+ rel_xpath = getXpathRelationExpression(element1, element2, "preceding", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1753
1763
  }
1754
1764
  if (relation === 4) {
1755
- rel_xpath = getXpathRelationExpression(element1, element2, "following", xpaths1, xpaths2, isIndex);
1765
+ rel_xpath = getXpathRelationExpression(element1, element2, "following", xpaths1, xpaths2, isIndex, multiElementReferenceMode);
1756
1766
  }
1757
1767
  if (rel_xpath) {
1758
1768
  finalXpaths = finalXpaths.concat(rel_xpath);
1759
1769
  }
1760
- const descendantXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descendant", isIndex);
1770
+ const descendantXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descendant", isIndex, multiElementReferenceMode);
1761
1771
  if (descendantXpath)
1762
1772
  finalXpaths = finalXpaths.concat(descendantXpath);
1763
- const descendantSelfXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descedant-or-self", isIndex);
1773
+ const descendantSelfXpath = getDescendantXpath([element1, element2], docmt, xpaths1, xpaths2, "descedant-or-self", isIndex, multiElementReferenceMode);
1764
1774
  if (descendantSelfXpath) {
1765
1775
  finalXpaths = finalXpaths.concat(descendantSelfXpath);
1766
1776
  }
@@ -1777,7 +1787,7 @@ const findRelativeXpath = (element1, element2, docmt, xpaths1, xpaths2, isIndex)
1777
1787
  return [finalXpaths[0]];
1778
1788
  }
1779
1789
  };
1780
- const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength) => {
1790
+ const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength = 0, multiElementReferenceMode = false) => {
1781
1791
  let finalExpectedElementXpath = "";
1782
1792
  if (xpath2.split(/\/(?=(?:[^']*\'[^\']*\')*[^\']*$)/g)?.length >=
1783
1793
  expCommonParentXpathElements.length) {
@@ -1791,7 +1801,7 @@ const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex
1791
1801
  const traverseXpath = getTraverseXpathExpression(`${step4 +
1792
1802
  (refCommonParentXpathElementLength
1793
1803
  ? "]".repeat(refCommonParentXpathElementLength)
1794
- : "")}`, xpaths2Els, refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex);
1804
+ : "")}`, xpaths2Els, refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex, multiElementReferenceMode);
1795
1805
  if (traverseXpath) {
1796
1806
  return traverseXpath;
1797
1807
  }
@@ -1828,7 +1838,7 @@ const descendantExpression = (refExpectElement, xpath2, relation, docmt, isIndex
1828
1838
  }
1829
1839
  }
1830
1840
  };
1831
- const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation, isIndex) => {
1841
+ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation, isIndex = false, multiElementReferenceMode = false) => {
1832
1842
  const refElement = refExpectElement[refExpectElement.length - 2];
1833
1843
  const expElement = refExpectElement[refExpectElement.length - 1];
1834
1844
  const expElementDocmnt = getShadowRoot(expElement) ?? expElement.ownerDocument;
@@ -1892,7 +1902,7 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1892
1902
  xpath2 = xpathData[i].value; // No need to modify the value
1893
1903
  }
1894
1904
  if (xpath2) {
1895
- return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength);
1905
+ return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength, multiElementReferenceMode);
1896
1906
  }
1897
1907
  }
1898
1908
  }
@@ -1919,7 +1929,7 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1919
1929
  else {
1920
1930
  xpath2 = xpathData[i].value; // No need to modify the value
1921
1931
  }
1922
- return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength);
1932
+ return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength, multiElementReferenceMode);
1923
1933
  }
1924
1934
  }
1925
1935
  }
@@ -1950,7 +1960,7 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1950
1960
  else {
1951
1961
  xpath2 = xpathData[i].value; // No need to modify the value
1952
1962
  }
1953
- return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength);
1963
+ return descendantExpression(refExpectElement, xpath2, relation, expElementDocmnt || docmt, isIndex, expCommonParentXpathElements, step4, refCommonParentXpathElementLength, multiElementReferenceMode);
1954
1964
  }
1955
1965
  }
1956
1966
  }
@@ -1963,12 +1973,12 @@ const getDescendantXpath = (refExpectElement, docmt, xpaths1, xpaths2, relation,
1963
1973
  const traverseXpath = getTraverseXpathExpression(`${step4 +
1964
1974
  (refCommonParentXpathElementLength
1965
1975
  ? "]".repeat(refCommonParentXpathElementLength)
1966
- : "")}`, expCommonParentXpathElements.reverse(), refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex);
1976
+ : "")}`, expCommonParentXpathElements, refExpectElement[refExpectElement.length - 1], refExpectElement, docmt, relation, isIndex, multiElementReferenceMode);
1967
1977
  if (traverseXpath) {
1968
1978
  return traverseXpath;
1969
1979
  }
1970
1980
  };
1971
- const getXpathRelationExpression = (element1, element2, relation, xpath1, xpath2, isIndex) => {
1981
+ const getXpathRelationExpression = (element1, element2, relation, xpath1, xpath2, isIndex, multiElementReferenceMode) => {
1972
1982
  let xpaths1;
1973
1983
  let xpaths2;
1974
1984
  console.log('getXpathRelationExpression', relation);
@@ -2035,7 +2045,7 @@ const getXpathRelationExpression = (element1, element2, relation, xpath1, xpath2
2035
2045
  if (xpath2Elements.length > 1) {
2036
2046
  const traverseXpath = getTraverseXpathExpression(`${xpaths1[i].value.indexOf("//") !== 0
2037
2047
  ? replaceActualAttributes(xpaths1[i].value, element1)
2038
- : replaceActualAttributes(xpaths1[i].value.substring(xpaths1[i].value.indexOf("//") + 2), element1)}`, xpath2Elements, element2, [element1, element2], element2.ownerDocument, relation, isIndex);
2048
+ : replaceActualAttributes(xpaths1[i].value.substring(xpaths1[i].value.indexOf("//") + 2), element1)}`, xpath2Elements, element2, [element1, element2], element2.ownerDocument, relation, isIndex, multiElementReferenceMode);
2039
2049
  console.log('getXpathRelationExpression traverseXpath', traverseXpath);
2040
2050
  if (traverseXpath) {
2041
2051
  finalXpaths.concat(traverseXpath);
@@ -2108,9 +2118,9 @@ const getReferenceElementXpath = (element) => {
2108
2118
  });
2109
2119
  return xpaths1;
2110
2120
  };
2111
- const getTraverseXpathExpression = (xpathe1, absoluteXpathElements, element2, refExpectElement, docmt, relation, isIndex) => {
2121
+ const getTraverseXpathExpression = (xpathe1, absoluteXpathElements, element2, refExpectElement, docmt, relation, isIndex, multiElementReferenceMode) => {
2112
2122
  let finalExpectedElementXpath;
2113
- {
2123
+ if (!multiElementReferenceMode) {
2114
2124
  for (let x = 1; x <= absoluteXpathElements.length; x++) {
2115
2125
  const xpath2 = absoluteXpathElements
2116
2126
  .slice(absoluteXpathElements.length - x, absoluteXpathElements.length)
@@ -2140,6 +2150,32 @@ const getTraverseXpathExpression = (xpathe1, absoluteXpathElements, element2, re
2140
2150
  }
2141
2151
  }
2142
2152
  }
2153
+ else {
2154
+ const xpath2 = absoluteXpathElements.join("/");
2155
+ finalExpectedElementXpath = `//${xpathe1}/${relation}::${replaceActualAttributes(xpath2)}`;
2156
+ const rel_count = getCountOfXPath(finalExpectedElementXpath, element2, docmt);
2157
+ if (rel_count === 1) {
2158
+ return [
2159
+ {
2160
+ key: `dynamic ${relation}`,
2161
+ value: replaceTempAttributes(finalExpectedElementXpath),
2162
+ },
2163
+ ];
2164
+ }
2165
+ if (rel_count > 1) {
2166
+ if (isIndex) {
2167
+ finalExpectedElementXpath = findXpathWithIndex(finalExpectedElementXpath, refExpectElement[refExpectElement.length - 1], docmt, rel_count);
2168
+ if (finalExpectedElementXpath) {
2169
+ return [
2170
+ {
2171
+ key: `dynamic ${relation}${isIndex ? " index" : ""}`,
2172
+ value: replaceTempAttributes(finalExpectedElementXpath),
2173
+ },
2174
+ ];
2175
+ }
2176
+ }
2177
+ }
2178
+ }
2143
2179
  };
2144
2180
  const referenceXpath = {
2145
2181
  findRelativeXpath,