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.
@@ -869,9 +869,9 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget) => {
869
869
  }
870
870
  return xpaths1;
871
871
  };
872
- const parseXml = (xmlStr) => {
872
+ const parseXml = (xmlStr, type) => {
873
873
  if (window.DOMParser) {
874
- return new window.DOMParser().parseFromString(xmlStr, "text/xml");
874
+ return new window.DOMParser().parseFromString(xmlStr, type);
875
875
  }
876
876
  return null;
877
877
  };
@@ -2189,10 +2189,27 @@ const referenceXpath = {
2189
2189
  getReferenceElementXpath,
2190
2190
  };
2191
2191
 
2192
- const getElementFromShadowRoot = (element, selector) => {
2193
- const shadowRoot = element.shadowRoot;
2194
- if (shadowRoot && !selector.includes("dynamic")) {
2195
- 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);
2196
2213
  }
2197
2214
  return null;
2198
2215
  };
@@ -2226,30 +2243,27 @@ const relations = [
2226
2243
  "/preceding",
2227
2244
  "/following",
2228
2245
  ];
2229
- function getElementFromXPath(tempDiv, xpath) {
2230
- let currentElement = tempDiv;
2231
- const window = currentElement.ownerDocument.defaultView;
2246
+ function getElementFromXPath(docmt, xpath) {
2247
+ const window = docmt.defaultView;
2232
2248
  if (!window)
2233
2249
  return null;
2234
2250
  const xpathEvaluator = new window.XPathEvaluator();
2235
- const xpathResult = xpathEvaluator.evaluate(xpath, currentElement.ownerDocument, //here even tempDiv can be passed
2236
- null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2251
+ const xpathResult = xpathEvaluator.evaluate(xpath, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2237
2252
  return xpathResult.singleNodeValue;
2238
2253
  }
2239
- function checkReferenceElementIsValid(locator, relation, tempDiv) {
2254
+ function checkReferenceElementIsValid(locator, relation, docmt) {
2240
2255
  if (locator.includes(relation)) {
2241
2256
  const locatotSplitArray = locator.split(relation);
2242
2257
  const sourceLoc = locatotSplitArray[0].trim();
2243
- let currentElement = tempDiv;
2244
- const window = currentElement.ownerDocument.defaultView;
2258
+ const window = docmt.defaultView;
2245
2259
  if (!window)
2246
2260
  return null;
2247
2261
  if (!locator.includes("dynamic")) {
2248
2262
  const xpathEvaluator = new window.XPathEvaluator();
2249
- 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);
2250
2264
  const sourceElement = xpathResult.singleNodeValue;
2251
2265
  if (sourceElement) {
2252
- 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);
2253
2267
  const completeElement = xpathResultComplete.singleNodeValue;
2254
2268
  let relativeXpath;
2255
2269
  if (completeElement) {
@@ -2270,16 +2284,12 @@ function checkReferenceElementIsValid(locator, relation, tempDiv) {
2270
2284
  return null;
2271
2285
  }
2272
2286
  const getElementsFromHTML = (record, docmt) => {
2273
- const document = docmt;
2274
- // global.SVGElement = document.defaultView?.SVGElement!;
2275
- const tempDiv = document.createElement("div");
2276
- 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");
2277
2288
  if (elementsToRemove) {
2278
2289
  elementsToRemove.forEach((tag) => {
2279
2290
  tag.remove();
2280
2291
  });
2281
2292
  }
2282
- tempDiv.innerHTML = document.body?.innerHTML;
2283
2293
  const finalLocatorsSet = new Set();
2284
2294
  let finalLocators = [];
2285
2295
  function createLocator(base, overrides = {}) {
@@ -2353,135 +2363,126 @@ const getElementsFromHTML = (record, docmt) => {
2353
2363
  if (record.isShared.includes("Y")) {
2354
2364
  break locators;
2355
2365
  }
2356
- for (const relation of relations) {
2357
- try {
2358
- let targetElement = null;
2359
- if (locator.value.startsWith("iframe")) {
2360
- const iframe = tempDiv.querySelector(locator.value);
2361
- if (iframe) {
2362
- const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
2363
- if (iframeDocument) {
2364
- targetElement = iframeDocument.querySelector(locator.value.slice(6));
2365
- }
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));
2366
2374
  }
2367
2375
  }
2368
- else {
2369
- const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
2370
- let currentElement = tempDiv;
2371
- for (const selector of selectors) {
2372
- if (currentElement) {
2373
- const trimmedSelector = selector.trim();
2374
- if (locator.name.includes("id") ||
2375
- trimmedSelector.startsWith("#")) {
2376
- targetElement = currentElement.querySelector("#" + trimmedSelector);
2377
- }
2378
- else if (locator.name.includes("className") ||
2379
- trimmedSelector.startsWith(".")) {
2380
- targetElement = currentElement.querySelector("." + trimmedSelector);
2381
- }
2382
- else if ((locator.name.includes("xpath") ||
2383
- trimmedSelector.startsWith("//")) &&
2384
- !locator.type.match("dynamic")) {
2385
- if (tempDiv?.innerHTML) {
2386
- const normalizedXPath = normalizeXPath(trimmedSelector);
2387
- targetElement = getElementFromXPath(tempDiv, normalizedXPath);
2388
- if (targetElement) {
2389
- createLocator(locator, {
2390
- value: trimmedSelector,
2391
- isRecorded: String(locator.isRecorded).includes("N")
2392
- ? "N"
2393
- : "Y",
2394
- });
2395
- }
2396
- }
2397
- }
2398
- else {
2399
- targetElement = currentElement.querySelector(trimmedSelector);
2400
- if (!targetElement) {
2401
- targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
2402
- }
2403
- }
2404
- if (!targetElement &&
2405
- isSvg(currentElement) &&
2406
- !locator.type.match("dynamic")) {
2407
- 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
+ });
2408
2402
  }
2409
- currentElement = targetElement;
2410
2403
  }
2411
2404
  else {
2412
- console.error("Element not found at:", selector);
2413
- break;
2405
+ targetElement = docmt.querySelector(trimmedSelector);
2406
+ if (!targetElement) {
2407
+ targetElement = getElementFromShadowRoot(docmt.body, trimmedSelector);
2408
+ }
2414
2409
  }
2415
2410
  }
2411
+ else {
2412
+ console.error("Element not found at:", selector);
2413
+ break;
2414
+ }
2416
2415
  }
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",
2434
- });
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",
2435
2434
  });
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",
2446
- });
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",
2447
2446
  });
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",
2462
- });
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",
2463
2462
  });
2464
- }
2465
- const classValue = getClassName(targetElement);
2466
- if (classValue &&
2467
- classValue.trim() !== "" &&
2468
- !locatorExists("className", classValue)) {
2469
- record.locators.forEach((loc) => {
2470
- createLocator(loc, {
2471
- name: "className",
2472
- value: classValue,
2473
- isRecorded: loc.value === classValue && loc.name === "className"
2474
- ? loc.isRecorded
2475
- : "Y",
2476
- isSelfHealed: loc.value === classValue && loc.name === "className"
2477
- ? loc.isSelfHealed
2478
- : "Y",
2479
- });
2463
+ });
2464
+ }
2465
+ const classValue = getClassName(targetElement);
2466
+ if (classValue &&
2467
+ classValue.trim() !== "" &&
2468
+ !locatorExists("className", classValue)) {
2469
+ record.locators.forEach((loc) => {
2470
+ createLocator(loc, {
2471
+ name: "className",
2472
+ value: classValue,
2473
+ isRecorded: loc.value === classValue && loc.name === "className"
2474
+ ? loc.isRecorded
2475
+ : "Y",
2476
+ isSelfHealed: loc.value === classValue && loc.name === "className"
2477
+ ? loc.isSelfHealed
2478
+ : "Y",
2480
2479
  });
2481
- }
2482
- const xpathResults = parseDOM(targetElement, document, false, true);
2483
- xpathResults.forEach((result) => {
2484
- const fnValue = result.value;
2480
+ });
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)) {
2485
2486
  record.locators.forEach((loc) => {
2486
2487
  createLocator(loc, {
2487
2488
  name: 'xpath',
@@ -2490,71 +2491,71 @@ const getElementsFromHTML = (record, docmt) => {
2490
2491
  isSelfHealed: loc.value === fnValue ? loc.isSelfHealed : 'Y',
2491
2492
  });
2492
2493
  });
2493
- });
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
- }
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) {