ff-dom 1.0.18-beta.6 → 2.0.0

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
  };
@@ -2188,10 +2188,27 @@
2188
2188
  getReferenceElementXpath,
2189
2189
  };
2190
2190
 
2191
- const getElementFromShadowRoot = (element, selector) => {
2192
- const shadowRoot = element.shadowRoot;
2193
- if (shadowRoot && !selector.includes("dynamic")) {
2194
- return shadowRoot.querySelector(selector);
2191
+ const getElementFromShadowRoot = (el, selector) => {
2192
+ // const shadowRoot = (element as HTMLElement).shadowRoot;
2193
+ // if (shadowRoot && !selector.includes("dynamic")) {
2194
+ // return shadowRoot.querySelector(selector);
2195
+ // }
2196
+ const elements = Array.from(el.querySelectorAll('*'));
2197
+ try {
2198
+ for (let i = 0; i < elements.length; i++) {
2199
+ if (elements[i].shadowRoot) {
2200
+ const { shadowRoot } = elements[i];
2201
+ if (shadowRoot) {
2202
+ getElementFromShadowRoot(shadowRoot, selector);
2203
+ if (shadowRoot && !selector.includes("dynamic")) {
2204
+ return shadowRoot.querySelector(selector);
2205
+ }
2206
+ }
2207
+ }
2208
+ }
2209
+ }
2210
+ catch (error) {
2211
+ console.log(error);
2195
2212
  }
2196
2213
  return null;
2197
2214
  };
@@ -2225,30 +2242,27 @@
2225
2242
  "/preceding",
2226
2243
  "/following",
2227
2244
  ];
2228
- function getElementFromXPath(tempDiv, xpath) {
2229
- let currentElement = tempDiv;
2230
- const window = currentElement.ownerDocument.defaultView;
2245
+ function getElementFromXPath(docmt, xpath) {
2246
+ const window = docmt.defaultView;
2231
2247
  if (!window)
2232
2248
  return null;
2233
2249
  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);
2250
+ const xpathResult = xpathEvaluator.evaluate(xpath, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2236
2251
  return xpathResult.singleNodeValue;
2237
2252
  }
2238
- function checkReferenceElementIsValid(locator, relation, tempDiv) {
2253
+ function checkReferenceElementIsValid(locator, relation, docmt) {
2239
2254
  if (locator.includes(relation)) {
2240
2255
  const locatotSplitArray = locator.split(relation);
2241
2256
  const sourceLoc = locatotSplitArray[0].trim();
2242
- let currentElement = tempDiv;
2243
- const window = currentElement.ownerDocument.defaultView;
2257
+ const window = docmt.defaultView;
2244
2258
  if (!window)
2245
2259
  return null;
2246
2260
  if (!locator.includes("dynamic")) {
2247
2261
  const xpathEvaluator = new window.XPathEvaluator();
2248
- const xpathResult = xpathEvaluator.evaluate(sourceLoc, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2262
+ const xpathResult = xpathEvaluator.evaluate(sourceLoc, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2249
2263
  const sourceElement = xpathResult.singleNodeValue;
2250
2264
  if (sourceElement) {
2251
- const xpathResultComplete = xpathEvaluator.evaluate(locator, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2265
+ const xpathResultComplete = xpathEvaluator.evaluate(locator, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2252
2266
  const completeElement = xpathResultComplete.singleNodeValue;
2253
2267
  let relativeXpath;
2254
2268
  if (completeElement) {
@@ -2269,16 +2283,12 @@
2269
2283
  return null;
2270
2284
  }
2271
2285
  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");
2286
+ const elementsToRemove = docmt.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
2276
2287
  if (elementsToRemove) {
2277
2288
  elementsToRemove.forEach((tag) => {
2278
2289
  tag.remove();
2279
2290
  });
2280
2291
  }
2281
- tempDiv.innerHTML = document.body?.innerHTML;
2282
2292
  const finalLocatorsSet = new Set();
2283
2293
  let finalLocators = [];
2284
2294
  function createLocator(base, overrides = {}) {
@@ -2352,135 +2362,126 @@
2352
2362
  if (record.isShared.includes("Y")) {
2353
2363
  break locators;
2354
2364
  }
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
- }
2365
+ try {
2366
+ let targetElement = null;
2367
+ if (locator.value.startsWith("iframe")) {
2368
+ const iframe = docmt.querySelector(locator.value);
2369
+ if (iframe) {
2370
+ const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
2371
+ if (iframeDocument) {
2372
+ targetElement = iframeDocument.querySelector(locator.value.slice(6));
2365
2373
  }
2366
2374
  }
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);
2375
+ }
2376
+ else {
2377
+ const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
2378
+ for (const selector of selectors) {
2379
+ if (docmt) {
2380
+ const trimmedSelector = selector.trim();
2381
+ if (locator.name.includes("id") ||
2382
+ trimmedSelector.startsWith("#")) {
2383
+ targetElement = docmt.querySelector("#" + trimmedSelector);
2384
+ }
2385
+ else if (locator.name.includes("className") ||
2386
+ trimmedSelector.startsWith(".")) {
2387
+ targetElement = docmt.querySelector("." + trimmedSelector);
2388
+ }
2389
+ else if ((locator.name.includes("xpath") ||
2390
+ trimmedSelector.startsWith("//")) &&
2391
+ !locator.type.match("dynamic")) {
2392
+ const normalizedXPath = normalizeXPath(trimmedSelector);
2393
+ targetElement = getElementFromXPath(docmt, normalizedXPath);
2394
+ if (targetElement) {
2395
+ createLocator(locator, {
2396
+ value: trimmedSelector,
2397
+ isRecorded: String(locator.isRecorded).includes("N")
2398
+ ? "N"
2399
+ : "Y",
2400
+ });
2407
2401
  }
2408
- currentElement = targetElement;
2409
2402
  }
2410
2403
  else {
2411
- console.error("Element not found at:", selector);
2412
- break;
2404
+ targetElement = docmt.querySelector(trimmedSelector);
2405
+ if (!targetElement) {
2406
+ targetElement = getElementFromShadowRoot(docmt.body, trimmedSelector);
2407
+ }
2413
2408
  }
2414
2409
  }
2410
+ else {
2411
+ console.error("Element not found at:", selector);
2412
+ break;
2413
+ }
2415
2414
  }
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
- });
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",
2434
2433
  });
2435
- }
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
- });
2434
+ });
2435
+ }
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",
2446
2445
  });
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
- });
2446
+ });
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",
2462
2461
  });
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
- });
2462
+ });
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",
2479
2478
  });
2480
- }
2481
- const xpathResults = parseDOM(targetElement, document, false, true);
2482
- xpathResults.forEach((result) => {
2483
- const fnValue = result.value;
2479
+ });
2480
+ }
2481
+ const xpathResults = parseDOM(targetElement, docmt, false, true);
2482
+ xpathResults.forEach((result) => {
2483
+ const fnValue = result.value;
2484
+ if (fnValue && !locatorExists(result.key.replace('xpath by', '').trim(), fnValue)) {
2484
2485
  record.locators.forEach((loc) => {
2485
2486
  createLocator(loc, {
2486
2487
  name: 'xpath',
@@ -2489,71 +2490,71 @@
2489
2490
  isSelfHealed: loc.value === fnValue ? loc.isSelfHealed : 'Y',
2490
2491
  });
2491
2492
  });
2492
- });
2493
- for (const locator of record.locators) {
2494
- try {
2495
- for (const loc of record.locators) {
2496
- if (!loc.value)
2497
- continue;
2498
- for (const relation of relations) {
2499
- if (loc.value.includes(relation)) {
2500
- const relativeXpath = checkReferenceElementIsValid(loc.value, relation, tempDiv);
2501
- if (relativeXpath) {
2502
- createLocator(loc, {
2503
- name: "xpath",
2504
- value: relativeXpath,
2505
- isRecorded: locator.isRecorded !== "" &&
2506
- locator.isRecorded !== null
2507
- ? locator.isRecorded
2508
- : "Y",
2509
- });
2510
- break;
2511
- }
2493
+ }
2494
+ });
2495
+ for (const locator of record.locators) {
2496
+ try {
2497
+ for (const loc of record.locators) {
2498
+ if (!loc.value)
2499
+ continue;
2500
+ for (const relation of relations) {
2501
+ if (loc.value.includes(relation)) {
2502
+ const relativeXpath = checkReferenceElementIsValid(loc.value, relation, docmt);
2503
+ if (relativeXpath) {
2504
+ createLocator(loc, {
2505
+ name: "xpath",
2506
+ value: relativeXpath,
2507
+ isRecorded: locator.isRecorded !== "" &&
2508
+ locator.isRecorded !== null
2509
+ ? locator.isRecorded
2510
+ : "Y",
2511
+ });
2512
+ break;
2512
2513
  }
2513
2514
  }
2514
2515
  }
2515
2516
  }
2516
- catch (error) {
2517
- console.error("Error processing locator:", locator, error);
2518
- }
2519
2517
  }
2520
- const finalAutoHealedLocators = finalLocators.map((obj) => ({
2521
- ...obj,
2522
- value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
2523
- }));
2524
- const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
2525
- if (locator.value &&
2526
- !unique.some((l) => l.value === locator.value)) {
2527
- unique.push(locator);
2528
- }
2529
- return unique;
2530
- }, []);
2531
- const jsonResult = [
2532
- {
2533
- name: `${record.name}`,
2534
- desc: `${record.desc}`,
2535
- type: `${record.type}`,
2536
- locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
2537
- isShared: `${record.isShared}`,
2538
- projectId: `${record.projectId}`,
2539
- projectType: `${record.projectType}`,
2540
- isRecorded: `${record.isRecorded}`,
2541
- folder: `${record.folder}`,
2542
- parentId: `${record.parentId}`,
2543
- parentName: `${record.parentName}`,
2544
- platform: `${record.platform}`,
2545
- licenseId: `${record.licenseId}`,
2546
- licenseType: `${record.licenseType}`,
2547
- userId: `${record.userId}`,
2548
- },
2549
- ];
2550
- return jsonResult;
2518
+ catch (error) {
2519
+ console.error("Error processing locator:", locator, error);
2520
+ }
2551
2521
  }
2522
+ const finalAutoHealedLocators = finalLocators.map((obj) => ({
2523
+ ...obj,
2524
+ value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
2525
+ }));
2526
+ const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
2527
+ if (locator.value &&
2528
+ !unique.some((l) => l.value === locator.value)) {
2529
+ unique.push(locator);
2530
+ }
2531
+ return unique;
2532
+ }, []);
2533
+ const jsonResult = [
2534
+ {
2535
+ name: `${record.name}`,
2536
+ desc: `${record.desc}`,
2537
+ type: `${record.type}`,
2538
+ locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
2539
+ isShared: `${record.isShared}`,
2540
+ projectId: `${record.projectId}`,
2541
+ projectType: `${record.projectType}`,
2542
+ isRecorded: `${record.isRecorded}`,
2543
+ folder: `${record.folder}`,
2544
+ parentId: `${record.parentId}`,
2545
+ parentName: `${record.parentName}`,
2546
+ platform: `${record.platform}`,
2547
+ licenseId: `${record.licenseId}`,
2548
+ licenseType: `${record.licenseType}`,
2549
+ userId: `${record.userId}`,
2550
+ },
2551
+ ];
2552
+ return jsonResult;
2552
2553
  }
2553
- catch (error) {
2554
- console.error("Error processing locator:", locator, error);
2555
- continue;
2556
- }
2554
+ }
2555
+ catch (error) {
2556
+ console.error("Error processing locator:", locator, error);
2557
+ continue;
2557
2558
  }
2558
2559
  }
2559
2560
  catch (error) {
@@ -45,7 +45,7 @@ export declare const createXPathAPI: () => {
45
45
  }[];
46
46
  };
47
47
  xpathUtils: {
48
- parseXml: (xmlStr: string) => Document | null;
48
+ parseXml: (xmlStr: string, type: DOMParserSupportedType) => Document | null;
49
49
  getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
50
50
  key: string;
51
51
  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
@@ -12,7 +12,7 @@ async function createXPathAPI() {
12
12
  let browser = await puppeteer.launch({ headless: 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 });\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":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ff-dom",
3
- "version": "1.0.18-beta.6",
3
+ "version": "2.0.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "files": [
package/src/node/xpath.ts CHANGED
@@ -18,7 +18,7 @@ async function createXPathAPI() {
18
18
  let page = await browser.newPage();
19
19
 
20
20
  const fromHTML = async (html: string) => {
21
- await page?.setContent(html);
21
+ await page?.setContent(html.replace(/\\n/g, '').replaceAll(/\\t/g, '').replace(/\\"/g, '"'), { waitUntil: 'domcontentloaded' });
22
22
  await page?.addScriptTag({ content: injectScript });
23
23
 
24
24
  page?.on(
@@ -59,12 +59,13 @@ async function createXPathAPI() {
59
59
 
60
60
  return {
61
61
  autoHeal: async (data: ElementRecord, htmlString: string) => {
62
- await page?.evaluate((datum: ElementRecord, html: string) => {
62
+ return await page?.evaluate((datum: ElementRecord) => {
63
63
  // @ts-ignore
64
64
  let xpathAPI = window.XpathLib.createXPathAPI();
65
- let docmt = xpathAPI.xpathUtils.parseXml(html);
66
- return xpathAPI.getElementsFromHTML(datum, docmt);
67
- }, data, htmlString);
65
+ let xpaths = xpathAPI.getElementsFromHTML(datum, document);
66
+ // console.log(xpaths);
67
+ return xpaths;
68
+ }, data);
68
69
  },
69
70
  };
70
71
  };