ff-dom 1.0.18-beta.5 → 1.0.18

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.
package/dist/index.cdn.js CHANGED
@@ -868,9 +868,9 @@
868
868
  }
869
869
  return xpaths1;
870
870
  };
871
- const parseXml = (xmlStr) => {
871
+ const parseXml = (xmlStr, type) => {
872
872
  if (window.DOMParser) {
873
- return new window.DOMParser().parseFromString(xmlStr, "text/xml");
873
+ return new window.DOMParser().parseFromString(xmlStr, type);
874
874
  }
875
875
  return null;
876
876
  };
@@ -1083,7 +1083,7 @@
1083
1083
  currentNode = currentNode.parentElement;
1084
1084
  }
1085
1085
  // Final constructed XPath
1086
- const finalXPath = xpathParts.join("");
1086
+ const finalXPath = xpathParts.join("") + nodeXpath;
1087
1087
  let count = getCountOfXPath(finalXPath, domNode, docmt);
1088
1088
  if (count === 1) {
1089
1089
  parentXpathCache.set(domNode, finalXPath); // Cache final result
@@ -1617,6 +1617,7 @@
1617
1617
  catch (error) {
1618
1618
  console.log(error);
1619
1619
  }
1620
+ return xpathData$1;
1620
1621
  };
1621
1622
  const parseDOM = (element, doc, isIndex, isTarget) => {
1622
1623
  xpathData$1 = [];
@@ -2188,10 +2189,27 @@
2188
2189
  getReferenceElementXpath,
2189
2190
  };
2190
2191
 
2191
- const getElementFromShadowRoot = (element, selector) => {
2192
- const shadowRoot = element.shadowRoot;
2193
- if (shadowRoot && !selector.includes("dynamic")) {
2194
- return shadowRoot.querySelector(selector);
2192
+ const getElementFromShadowRoot = (el, selector) => {
2193
+ // const shadowRoot = (element as HTMLElement).shadowRoot;
2194
+ // if (shadowRoot && !selector.includes("dynamic")) {
2195
+ // return shadowRoot.querySelector(selector);
2196
+ // }
2197
+ const elements = Array.from(el.querySelectorAll('*'));
2198
+ try {
2199
+ for (let i = 0; i < elements.length; i++) {
2200
+ if (elements[i].shadowRoot) {
2201
+ const { shadowRoot } = elements[i];
2202
+ if (shadowRoot) {
2203
+ getElementFromShadowRoot(shadowRoot, selector);
2204
+ if (shadowRoot && !selector.includes("dynamic")) {
2205
+ return shadowRoot.querySelector(selector);
2206
+ }
2207
+ }
2208
+ }
2209
+ }
2210
+ }
2211
+ catch (error) {
2212
+ console.log(error);
2195
2213
  }
2196
2214
  return null;
2197
2215
  };
@@ -2225,30 +2243,27 @@
2225
2243
  "/preceding",
2226
2244
  "/following",
2227
2245
  ];
2228
- function getElementFromXPath(tempDiv, xpath) {
2229
- let currentElement = tempDiv;
2230
- const window = currentElement.ownerDocument.defaultView;
2246
+ function getElementFromXPath(docmt, xpath) {
2247
+ const window = docmt.defaultView;
2231
2248
  if (!window)
2232
2249
  return null;
2233
2250
  const xpathEvaluator = new window.XPathEvaluator();
2234
- const xpathResult = xpathEvaluator.evaluate(xpath, currentElement.ownerDocument, //here even tempDiv can be passed
2235
- null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2251
+ const xpathResult = xpathEvaluator.evaluate(xpath, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2236
2252
  return xpathResult.singleNodeValue;
2237
2253
  }
2238
- function checkReferenceElementIsValid(locator, relation, tempDiv) {
2254
+ function checkReferenceElementIsValid(locator, relation, docmt) {
2239
2255
  if (locator.includes(relation)) {
2240
2256
  const locatotSplitArray = locator.split(relation);
2241
2257
  const sourceLoc = locatotSplitArray[0].trim();
2242
- let currentElement = tempDiv;
2243
- const window = currentElement.ownerDocument.defaultView;
2258
+ const window = docmt.defaultView;
2244
2259
  if (!window)
2245
2260
  return null;
2246
2261
  if (!locator.includes("dynamic")) {
2247
2262
  const xpathEvaluator = new window.XPathEvaluator();
2248
- const xpathResult = xpathEvaluator.evaluate(sourceLoc, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2263
+ const xpathResult = xpathEvaluator.evaluate(sourceLoc, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2249
2264
  const sourceElement = xpathResult.singleNodeValue;
2250
2265
  if (sourceElement) {
2251
- const xpathResultComplete = xpathEvaluator.evaluate(locator, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2266
+ const xpathResultComplete = xpathEvaluator.evaluate(locator, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2252
2267
  const completeElement = xpathResultComplete.singleNodeValue;
2253
2268
  let relativeXpath;
2254
2269
  if (completeElement) {
@@ -2269,16 +2284,12 @@
2269
2284
  return null;
2270
2285
  }
2271
2286
  const getElementsFromHTML = (record, docmt) => {
2272
- const document = docmt;
2273
- // global.SVGElement = document.defaultView?.SVGElement!;
2274
- const tempDiv = document.createElement("div");
2275
- const elementsToRemove = document.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
2287
+ const elementsToRemove = docmt.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
2276
2288
  if (elementsToRemove) {
2277
2289
  elementsToRemove.forEach((tag) => {
2278
2290
  tag.remove();
2279
2291
  });
2280
2292
  }
2281
- tempDiv.innerHTML = document.body.innerHTML;
2282
2293
  const finalLocatorsSet = new Set();
2283
2294
  let finalLocators = [];
2284
2295
  function createLocator(base, overrides = {}) {
@@ -2352,209 +2363,199 @@
2352
2363
  if (record.isShared.includes("Y")) {
2353
2364
  break locators;
2354
2365
  }
2355
- for (const relation of relations) {
2356
- try {
2357
- let targetElement = null;
2358
- if (locator.value.startsWith("iframe")) {
2359
- const iframe = tempDiv.querySelector(locator.value);
2360
- if (iframe) {
2361
- const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
2362
- if (iframeDocument) {
2363
- targetElement = iframeDocument.querySelector(locator.value.slice(6));
2364
- }
2366
+ try {
2367
+ let targetElement = null;
2368
+ if (locator.value.startsWith("iframe")) {
2369
+ const iframe = docmt.querySelector(locator.value);
2370
+ if (iframe) {
2371
+ const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
2372
+ if (iframeDocument) {
2373
+ targetElement = iframeDocument.querySelector(locator.value.slice(6));
2365
2374
  }
2366
2375
  }
2367
- else {
2368
- const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
2369
- let currentElement = tempDiv;
2370
- for (const selector of selectors) {
2371
- if (currentElement) {
2372
- const trimmedSelector = selector.trim();
2373
- if (locator.name.includes("id") ||
2374
- trimmedSelector.startsWith("#")) {
2375
- targetElement = currentElement.querySelector("#" + trimmedSelector);
2376
- }
2377
- else if (locator.name.includes("className") ||
2378
- trimmedSelector.startsWith(".")) {
2379
- targetElement = currentElement.querySelector("." + trimmedSelector);
2380
- }
2381
- else if ((locator.name.includes("xpath") ||
2382
- trimmedSelector.startsWith("//")) &&
2383
- !locator.type.match("dynamic")) {
2384
- if (tempDiv.innerHTML) {
2385
- const normalizedXPath = normalizeXPath(trimmedSelector);
2386
- targetElement = getElementFromXPath(tempDiv, normalizedXPath);
2387
- if (targetElement) {
2388
- createLocator(locator, {
2389
- value: trimmedSelector,
2390
- isRecorded: String(locator.isRecorded).includes("N")
2391
- ? "N"
2392
- : "Y",
2393
- });
2394
- }
2395
- }
2396
- }
2397
- else {
2398
- targetElement = currentElement.querySelector(trimmedSelector);
2399
- if (!targetElement) {
2400
- targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
2401
- }
2402
- }
2403
- if (!targetElement &&
2404
- isSvg(currentElement) &&
2405
- !locator.type.match("dynamic")) {
2406
- targetElement = currentElement.querySelector(trimmedSelector);
2376
+ }
2377
+ else {
2378
+ const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
2379
+ for (const selector of selectors) {
2380
+ if (docmt) {
2381
+ const trimmedSelector = selector.trim();
2382
+ if (locator.name.includes("id") ||
2383
+ trimmedSelector.startsWith("#")) {
2384
+ targetElement = docmt.querySelector("#" + trimmedSelector);
2385
+ }
2386
+ else if (locator.name.includes("className") ||
2387
+ trimmedSelector.startsWith(".")) {
2388
+ targetElement = docmt.querySelector("." + trimmedSelector);
2389
+ }
2390
+ else if ((locator.name.includes("xpath") ||
2391
+ trimmedSelector.startsWith("//")) &&
2392
+ !locator.type.match("dynamic")) {
2393
+ const normalizedXPath = normalizeXPath(trimmedSelector);
2394
+ targetElement = getElementFromXPath(docmt, normalizedXPath);
2395
+ if (targetElement) {
2396
+ createLocator(locator, {
2397
+ value: trimmedSelector,
2398
+ isRecorded: String(locator.isRecorded).includes("N")
2399
+ ? "N"
2400
+ : "Y",
2401
+ });
2407
2402
  }
2408
- currentElement = targetElement;
2409
2403
  }
2410
2404
  else {
2411
- console.error("Element not found at:", selector);
2412
- break;
2405
+ targetElement = docmt.querySelector(trimmedSelector);
2406
+ if (!targetElement) {
2407
+ targetElement = getElementFromShadowRoot(docmt.body, trimmedSelector);
2408
+ }
2413
2409
  }
2414
2410
  }
2415
- }
2416
- const locatorExists = (name, value) => {
2417
- const key = `${name}:${value}`;
2418
- return finalLocatorsSet.has(key);
2419
- };
2420
- if (targetElement) {
2421
- const idValue = getId(targetElement);
2422
- if (idValue && !locatorExists("id", idValue)) {
2423
- record.locators.forEach((loc) => {
2424
- createLocator(loc, {
2425
- name: "id",
2426
- value: idValue,
2427
- isRecorded: loc.value === idValue && loc.name === "id"
2428
- ? loc.isRecorded
2429
- : "Y",
2430
- isSelfHealed: loc.value === idValue && loc.name === "id"
2431
- ? loc.isSelfHealed
2432
- : "Y",
2433
- });
2434
- });
2411
+ else {
2412
+ console.error("Element not found at:", selector);
2413
+ break;
2435
2414
  }
2436
- const textValue = getVisibleText(targetElement);
2437
- if (textValue) {
2438
- record.locators.forEach((loc) => {
2439
- createLocator(loc, {
2440
- name: "linkText",
2441
- type: "static",
2442
- value: textValue,
2443
- isRecorded: loc.value === textValue ? loc.isRecorded : "Y",
2444
- isSelfHealed: loc.value === textValue ? loc.isSelfHealed : "Y",
2445
- });
2415
+ }
2416
+ }
2417
+ const locatorExists = (name, value) => {
2418
+ const key = `${name}:${value}`;
2419
+ return finalLocatorsSet.has(key);
2420
+ };
2421
+ if (targetElement) {
2422
+ const idValue = getId(targetElement);
2423
+ if (idValue && !locatorExists("id", idValue)) {
2424
+ record.locators.forEach((loc) => {
2425
+ createLocator(loc, {
2426
+ name: "id",
2427
+ value: idValue,
2428
+ isRecorded: loc.value === idValue && loc.name === "id"
2429
+ ? loc.isRecorded
2430
+ : "Y",
2431
+ isSelfHealed: loc.value === idValue && loc.name === "id"
2432
+ ? loc.isSelfHealed
2433
+ : "Y",
2446
2434
  });
2447
- }
2448
- const nameLocator = getName(targetElement);
2449
- if (nameLocator && !locatorExists("name", nameLocator)) {
2450
- record.locators.forEach((loc) => {
2451
- createLocator(loc, {
2452
- name: "name",
2453
- type: "static",
2454
- value: nameLocator,
2455
- isRecorded: loc.value === nameLocator && loc.name === "name"
2456
- ? loc.isRecorded
2457
- : "Y",
2458
- isSelfHealed: loc.value === nameLocator && loc.name === "name"
2459
- ? loc.isSelfHealed
2460
- : "Y",
2461
- });
2435
+ });
2436
+ }
2437
+ const textValue = getVisibleText(targetElement);
2438
+ if (textValue) {
2439
+ record.locators.forEach((loc) => {
2440
+ createLocator(loc, {
2441
+ name: "linkText",
2442
+ type: "static",
2443
+ value: textValue,
2444
+ isRecorded: loc.value === textValue ? loc.isRecorded : "Y",
2445
+ isSelfHealed: loc.value === textValue ? loc.isSelfHealed : "Y",
2462
2446
  });
2463
- }
2464
- const classValue = getClassName(targetElement);
2465
- if (classValue &&
2466
- classValue.trim() !== "" &&
2467
- !locatorExists("className", classValue)) {
2468
- record.locators.forEach((loc) => {
2469
- createLocator(loc, {
2470
- name: "className",
2471
- value: classValue,
2472
- isRecorded: loc.value === classValue && loc.name === "className"
2473
- ? loc.isRecorded
2474
- : "Y",
2475
- isSelfHealed: loc.value === classValue && loc.name === "className"
2476
- ? loc.isSelfHealed
2477
- : "Y",
2478
- });
2447
+ });
2448
+ }
2449
+ const nameLocator = getName(targetElement);
2450
+ if (nameLocator && !locatorExists("name", nameLocator)) {
2451
+ record.locators.forEach((loc) => {
2452
+ createLocator(loc, {
2453
+ name: "name",
2454
+ type: "static",
2455
+ value: nameLocator,
2456
+ isRecorded: loc.value === nameLocator && loc.name === "name"
2457
+ ? loc.isRecorded
2458
+ : "Y",
2459
+ isSelfHealed: loc.value === nameLocator && loc.name === "name"
2460
+ ? loc.isSelfHealed
2461
+ : "Y",
2479
2462
  });
2480
- }
2481
- const fnValue = parseDOM(targetElement, document, false, true);
2463
+ });
2464
+ }
2465
+ const classValue = getClassName(targetElement);
2466
+ if (classValue &&
2467
+ classValue.trim() !== "" &&
2468
+ !locatorExists("className", classValue)) {
2482
2469
  record.locators.forEach((loc) => {
2483
2470
  createLocator(loc, {
2484
- name: 'xpath',
2485
- value: fnValue,
2486
- isRecorded: fnValue?.find((x) => x.value === loc.value)
2471
+ name: "className",
2472
+ value: classValue,
2473
+ isRecorded: loc.value === classValue && loc.name === "className"
2487
2474
  ? loc.isRecorded
2488
2475
  : "Y",
2489
- isSelfHealed: fnValue?.find((x) => x.value === loc.value)
2476
+ isSelfHealed: loc.value === classValue && loc.name === "className"
2490
2477
  ? loc.isSelfHealed
2491
2478
  : "Y",
2492
2479
  });
2493
2480
  });
2494
- for (const locator of record.locators) {
2495
- try {
2496
- for (const loc of record.locators) {
2497
- if (!loc.value)
2498
- continue;
2499
- for (const relation of relations) {
2500
- if (loc.value.includes(relation)) {
2501
- const relativeXpath = checkReferenceElementIsValid(loc.value, relation, tempDiv);
2502
- if (relativeXpath) {
2503
- createLocator(loc, {
2504
- name: "xpath",
2505
- value: relativeXpath,
2506
- isRecorded: locator.isRecorded !== "" &&
2507
- locator.isRecorded !== null
2508
- ? locator.isRecorded
2509
- : "Y",
2510
- });
2511
- break;
2512
- }
2481
+ }
2482
+ const xpathResults = parseDOM(targetElement, docmt, false, true);
2483
+ xpathResults.forEach((result) => {
2484
+ const fnValue = result.value;
2485
+ if (fnValue && !locatorExists(result.key.replace('xpath by', '').trim(), fnValue)) {
2486
+ record.locators.forEach((loc) => {
2487
+ createLocator(loc, {
2488
+ name: 'xpath',
2489
+ value: fnValue,
2490
+ isRecorded: loc.value === fnValue ? loc.isRecorded : 'Y',
2491
+ isSelfHealed: loc.value === fnValue ? loc.isSelfHealed : 'Y',
2492
+ });
2493
+ });
2494
+ }
2495
+ });
2496
+ for (const locator of record.locators) {
2497
+ try {
2498
+ for (const loc of record.locators) {
2499
+ if (!loc.value)
2500
+ continue;
2501
+ for (const relation of relations) {
2502
+ if (loc.value.includes(relation)) {
2503
+ const relativeXpath = checkReferenceElementIsValid(loc.value, relation, docmt);
2504
+ if (relativeXpath) {
2505
+ createLocator(loc, {
2506
+ name: "xpath",
2507
+ value: relativeXpath,
2508
+ isRecorded: locator.isRecorded !== "" &&
2509
+ locator.isRecorded !== null
2510
+ ? locator.isRecorded
2511
+ : "Y",
2512
+ });
2513
+ break;
2513
2514
  }
2514
2515
  }
2515
2516
  }
2516
2517
  }
2517
- catch (error) {
2518
- console.error("Error processing locator:", locator, error);
2519
- }
2520
2518
  }
2521
- const finalAutoHealedLocators = finalLocators.map((obj) => ({
2522
- ...obj,
2523
- value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
2524
- }));
2525
- const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
2526
- if (locator.value &&
2527
- !unique.some((l) => l.value === locator.value)) {
2528
- unique.push(locator);
2529
- }
2530
- return unique;
2531
- }, []);
2532
- const jsonResult = [
2533
- {
2534
- name: `${record.name}`,
2535
- desc: `${record.desc}`,
2536
- type: `${record.type}`,
2537
- locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
2538
- isShared: `${record.isShared}`,
2539
- projectId: `${record.projectId}`,
2540
- projectType: `${record.projectType}`,
2541
- isRecorded: `${record.isRecorded}`,
2542
- folder: `${record.folder}`,
2543
- parentId: `${record.parentId}`,
2544
- parentName: `${record.parentName}`,
2545
- platform: `${record.platform}`,
2546
- licenseId: `${record.licenseId}`,
2547
- licenseType: `${record.licenseType}`,
2548
- userId: `${record.userId}`,
2549
- },
2550
- ];
2551
- return jsonResult;
2519
+ catch (error) {
2520
+ console.error("Error processing locator:", locator, error);
2521
+ }
2552
2522
  }
2523
+ const finalAutoHealedLocators = finalLocators.map((obj) => ({
2524
+ ...obj,
2525
+ value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
2526
+ }));
2527
+ const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
2528
+ if (locator.value &&
2529
+ !unique.some((l) => l.value === locator.value)) {
2530
+ unique.push(locator);
2531
+ }
2532
+ return unique;
2533
+ }, []);
2534
+ const jsonResult = [
2535
+ {
2536
+ name: `${record.name}`,
2537
+ desc: `${record.desc}`,
2538
+ type: `${record.type}`,
2539
+ locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
2540
+ isShared: `${record.isShared}`,
2541
+ projectId: `${record.projectId}`,
2542
+ projectType: `${record.projectType}`,
2543
+ isRecorded: `${record.isRecorded}`,
2544
+ folder: `${record.folder}`,
2545
+ parentId: `${record.parentId}`,
2546
+ parentName: `${record.parentName}`,
2547
+ platform: `${record.platform}`,
2548
+ licenseId: `${record.licenseId}`,
2549
+ licenseType: `${record.licenseType}`,
2550
+ userId: `${record.userId}`,
2551
+ },
2552
+ ];
2553
+ return jsonResult;
2553
2554
  }
2554
- catch (error) {
2555
- console.error("Error processing locator:", locator, error);
2556
- continue;
2557
- }
2555
+ }
2556
+ catch (error) {
2557
+ console.error("Error processing locator:", locator, error);
2558
+ continue;
2558
2559
  }
2559
2560
  }
2560
2561
  catch (error) {
@@ -7,7 +7,10 @@ export declare const createXPathAPI: () => {
7
7
  getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
8
8
  getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
9
9
  attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
10
- addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => void;
10
+ addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => {
11
+ key: string;
12
+ value: string;
13
+ }[];
11
14
  addRelativeXpaths: (targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean, attribute: Attr[]) => {
12
15
  key: string;
13
16
  value: string;
@@ -45,7 +48,7 @@ export declare const createXPathAPI: () => {
45
48
  }[];
46
49
  };
47
50
  xpathUtils: {
48
- parseXml: (xmlStr: string) => Document | null;
51
+ parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
49
52
  getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
50
53
  key: string;
51
54
  value: string;
@@ -14,7 +14,10 @@ declare const xpath: {
14
14
  getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
15
15
  getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
16
16
  attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
17
- addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => void;
17
+ addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => {
18
+ key: string;
19
+ value: string;
20
+ }[];
18
21
  addRelativeXpaths: (targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean, attribute: Attr[]) => {
19
22
  key: string;
20
23
  value: string;
@@ -45,11 +45,11 @@ export declare const getReferenceElementsXpath: (domNode: HTMLElement | Element,
45
45
  key: string;
46
46
  value: string;
47
47
  }[];
48
- export declare const parseXml: (xmlStr: string) => Document | null;
48
+ export declare const parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
49
49
  export declare const normalizeXPath: (xpath: string) => string;
50
50
  export declare const findMatchingParenthesis: (text: string, openPos: number) => number;
51
51
  export declare const xpathUtils: {
52
- parseXml: (xmlStr: string) => Document | null;
52
+ parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
53
53
  getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
54
54
  key: string;
55
55
  value: string;
@@ -1,7 +1,7 @@
1
1
  import { ElementRecord } from "../types/locator";
2
2
  declare function createXPathAPI(): Promise<{
3
3
  fromHTML: (html: string) => Promise<{
4
- autoHeal: (data: ElementRecord, htmlString: string) => Promise<void>;
4
+ autoHeal: (data: ElementRecord, htmlString: string) => Promise<any>;
5
5
  }>;
6
6
  browser: any;
7
7
  }>;
package/dist/xpath.mjs CHANGED
@@ -9,10 +9,10 @@ const injectScriptPath = join(_dirname, "index.cdn.js");
9
9
  const injectScript = readFileSync(injectScriptPath, "utf-8");
10
10
  async function createXPathAPI() {
11
11
  puppeteer = await import('puppeteer');
12
- let browser = await puppeteer.launch({ headless: true });
12
+ let browser = await puppeteer.launch({ headless: true, debugger: true });
13
13
  let page = await browser.newPage();
14
14
  const fromHTML = async (html) => {
15
- await page?.setContent(html);
15
+ await page?.setContent(html.replace(/\\n/g, '').replaceAll(/\\t/g, '').replace(/\\"/g, '"'), { waitUntil: 'domcontentloaded' });
16
16
  await page?.addScriptTag({ content: injectScript });
17
17
  page?.on("console", async (msg) => {
18
18
  const type = msg.type();
@@ -45,12 +45,13 @@ async function createXPathAPI() {
45
45
  });
46
46
  return {
47
47
  autoHeal: async (data, htmlString) => {
48
- await page?.evaluate((datum, html) => {
48
+ return await page?.evaluate((datum) => {
49
49
  // @ts-ignore
50
50
  let xpathAPI = window.XpathLib.createXPathAPI();
51
- let docmt = xpathAPI.xpathUtils.parseXml(html);
52
- return xpathAPI.getElementsFromHTML(datum, docmt);
53
- }, data, htmlString);
51
+ let xpaths = xpathAPI.getElementsFromHTML(datum, document);
52
+ // console.log(xpaths);
53
+ return xpaths;
54
+ }, data);
54
55
  },
55
56
  };
56
57
  };
@@ -1 +1 @@
1
- {"version":3,"file":"xpath.mjs","sources":["../src/node/xpath.ts"],"sourcesContent":["import { fileURLToPath } from \"url\";\r\nimport path, { join } from \"path\";\r\nimport { readFileSync } from \"fs\";\r\nimport { ElementRecord } from \"../types/locator\";\r\n\r\nconst _filename = fileURLToPath(import.meta.url);\r\nconst _dirname = path.dirname(_filename);\r\n\r\nlet puppeteer: any;\r\n\r\nconst injectScriptPath = join(_dirname, \"index.cdn.js\");\r\nconst injectScript = readFileSync(injectScriptPath, \"utf-8\");\r\n\r\nasync function createXPathAPI() {\r\n puppeteer = await import('puppeteer');\r\n\r\n let browser = await puppeteer.launch({ headless: true });\r\n let page = await browser.newPage();\r\n\r\n const fromHTML = async (html: string) => {\r\n await page?.setContent(html);\r\n await page?.addScriptTag({ content: injectScript });\r\n\r\n page?.on(\r\n \"console\",\r\n async (msg: { type: () => any; text: () => any; args: () => any }) => {\r\n const type = msg.type();\r\n const txt = msg.text();\r\n\r\n const args = msg.args();\r\n if (!args || args.length === 0) {\r\n console.log(`[Browser:${type}]`, txt);\r\n return;\r\n }\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n try {\r\n const arg = args[i];\r\n const obj = arg.remoteObject();\r\n\r\n console.log(obj);\r\n\r\n if (obj.value !== undefined) {\r\n console.log(`[Browser:${type}]`, obj.value);\r\n } else {\r\n const value = await arg.jsonValue().catch(() => txt);\r\n console.log(`[Browser:${type}]`, value);\r\n }\r\n } catch (err) {\r\n console.log(`[Browser:${type}]`, txt);\r\n }\r\n }\r\n }\r\n );\r\n\r\n page?.on(\"pageerror\", (msg: any) => {\r\n console.log(\"error\", msg);\r\n });\r\n\r\n return {\r\n autoHeal: async (data: ElementRecord, htmlString: string) => {\r\n await page?.evaluate((datum: ElementRecord, html: string) => {\r\n // @ts-ignore\r\n let xpathAPI = window.XpathLib.createXPathAPI();\r\n let docmt = xpathAPI.xpathUtils.parseXml(html);\r\n return xpathAPI.getElementsFromHTML(datum, docmt);\r\n }, data, htmlString);\r\n },\r\n };\r\n };\r\n\r\n return { fromHTML, browser };\r\n}\r\n\r\nexport default createXPathAPI;\r\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xpath.mjs","sources":["../src/node/xpath.ts"],"sourcesContent":["import { fileURLToPath } from \"url\";\r\nimport path, { join } from \"path\";\r\nimport { readFileSync } from \"fs\";\r\nimport { ElementRecord } from \"../types/locator\";\r\n\r\nconst _filename = fileURLToPath(import.meta.url);\r\nconst _dirname = path.dirname(_filename);\r\n\r\nlet puppeteer: any;\r\n\r\nconst injectScriptPath = join(_dirname, \"index.cdn.js\");\r\nconst injectScript = readFileSync(injectScriptPath, \"utf-8\");\r\n\r\nasync function createXPathAPI() {\r\n puppeteer = await import('puppeteer');\r\n\r\n let browser = await puppeteer.launch({ headless: true, debugger: true });\r\n let page = await browser.newPage();\r\n\r\n const fromHTML = async (html: string) => {\r\n await page?.setContent(html.replace(/\\\\n/g, '').replaceAll(/\\\\t/g, '').replace(/\\\\\"/g, '\"'), { waitUntil: 'domcontentloaded' });\r\n await page?.addScriptTag({ content: injectScript });\r\n\r\n page?.on(\r\n \"console\",\r\n async (msg: { type: () => any; text: () => any; args: () => any }) => {\r\n const type = msg.type();\r\n const txt = msg.text();\r\n\r\n const args = msg.args();\r\n if (!args || args.length === 0) {\r\n console.log(`[Browser:${type}]`, txt);\r\n return;\r\n }\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n try {\r\n const arg = args[i];\r\n const obj = arg.remoteObject();\r\n\r\n console.log(obj);\r\n\r\n if (obj.value !== undefined) {\r\n console.log(`[Browser:${type}]`, obj.value);\r\n } else {\r\n const value = await arg.jsonValue().catch(() => txt);\r\n console.log(`[Browser:${type}]`, value);\r\n }\r\n } catch (err) {\r\n console.log(`[Browser:${type}]`, txt);\r\n }\r\n }\r\n }\r\n );\r\n\r\n page?.on(\"pageerror\", (msg: any) => {\r\n console.log(\"error\", msg);\r\n });\r\n\r\n return {\r\n autoHeal: async (data: ElementRecord, htmlString: string) => {\r\n return await page?.evaluate((datum: ElementRecord) => {\r\n // @ts-ignore\r\n let xpathAPI = window.XpathLib.createXPathAPI();\r\n let xpaths = xpathAPI.getElementsFromHTML(datum, document);\r\n // console.log(xpaths);\r\n return xpaths;\r\n }, data);\r\n },\r\n };\r\n };\r\n\r\n return { fromHTML, browser };\r\n}\r\n\r\nexport default createXPathAPI;\r\n"],"names":[],"mappings":";;;;AAKA,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;AAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;AAExC,IAAI,SAAc;AAElB,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC;AACvD,MAAM,YAAY,GAAG,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC;AAE5D,eAAe,cAAc,GAAA;AAC3B,IAAA,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AAErC,IAAA,IAAI,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACxE,IAAA,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE;AAElC,IAAA,MAAM,QAAQ,GAAG,OAAO,IAAY,KAAI;AACtC,QAAA,MAAM,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;QAC/H,MAAM,IAAI,EAAE,YAAY,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAEnD,IAAI,EAAE,EAAE,CACN,SAAS,EACT,OAAO,GAA0D,KAAI;AACnE,YAAA,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE;AACvB,YAAA,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,EAAE;AAEtB,YAAA,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE;YACvB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;gBAC9B,OAAO,CAAC,GAAG,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,CAAA,CAAG,EAAE,GAAG,CAAC;gBACrC;YACF;AAEA,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACpC,gBAAA,IAAI;AACF,oBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;AACnB,oBAAA,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE;AAE9B,oBAAA,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AAEhB,oBAAA,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE;wBAC3B,OAAO,CAAC,GAAG,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,CAAA,CAAG,EAAE,GAAG,CAAC,KAAK,CAAC;oBAC7C;yBAAO;AACL,wBAAA,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;wBACpD,OAAO,CAAC,GAAG,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,CAAA,CAAG,EAAE,KAAK,CAAC;oBACzC;gBACF;gBAAE,OAAO,GAAG,EAAE;oBACZ,OAAO,CAAC,GAAG,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,CAAA,CAAG,EAAE,GAAG,CAAC;gBACvC;YACF;AACF,QAAA,CAAC,CACF;QAED,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,GAAQ,KAAI;AACjC,YAAA,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC;AAC3B,QAAA,CAAC,CAAC;QAEF,OAAO;AACL,YAAA,QAAQ,EAAE,OAAO,IAAmB,EAAE,UAAkB,KAAI;gBAC1D,OAAO,MAAM,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAoB,KAAI;;oBAEnD,IAAI,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE;oBAC/C,IAAI,MAAM,GAAG,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC;;AAE1D,oBAAA,OAAO,MAAM;gBACf,CAAC,EAAE,IAAI,CAAC;YACV,CAAC;SACF;AACH,IAAA,CAAC;AAED,IAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE;AAC9B;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ff-dom",
3
- "version": "1.0.18-beta.5",
3
+ "version": "1.0.18",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "files": [