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.
@@ -865,9 +865,9 @@ const getReferenceElementsXpath = (domNode, docmt, isTarget) => {
865
865
  }
866
866
  return xpaths1;
867
867
  };
868
- const parseXml = (xmlStr) => {
868
+ const parseXml = (xmlStr, type) => {
869
869
  if (window.DOMParser) {
870
- return new window.DOMParser().parseFromString(xmlStr, "text/xml");
870
+ return new window.DOMParser().parseFromString(xmlStr, type);
871
871
  }
872
872
  return null;
873
873
  };
@@ -2185,10 +2185,27 @@ const referenceXpath = {
2185
2185
  getReferenceElementXpath,
2186
2186
  };
2187
2187
 
2188
- const getElementFromShadowRoot = (element, selector) => {
2189
- const shadowRoot = element.shadowRoot;
2190
- if (shadowRoot && !selector.includes("dynamic")) {
2191
- return shadowRoot.querySelector(selector);
2188
+ const getElementFromShadowRoot = (el, selector) => {
2189
+ // const shadowRoot = (element as HTMLElement).shadowRoot;
2190
+ // if (shadowRoot && !selector.includes("dynamic")) {
2191
+ // return shadowRoot.querySelector(selector);
2192
+ // }
2193
+ const elements = Array.from(el.querySelectorAll('*'));
2194
+ try {
2195
+ for (let i = 0; i < elements.length; i++) {
2196
+ if (elements[i].shadowRoot) {
2197
+ const { shadowRoot } = elements[i];
2198
+ if (shadowRoot) {
2199
+ getElementFromShadowRoot(shadowRoot, selector);
2200
+ if (shadowRoot && !selector.includes("dynamic")) {
2201
+ return shadowRoot.querySelector(selector);
2202
+ }
2203
+ }
2204
+ }
2205
+ }
2206
+ }
2207
+ catch (error) {
2208
+ console.log(error);
2192
2209
  }
2193
2210
  return null;
2194
2211
  };
@@ -2222,30 +2239,27 @@ const relations = [
2222
2239
  "/preceding",
2223
2240
  "/following",
2224
2241
  ];
2225
- function getElementFromXPath(tempDiv, xpath) {
2226
- let currentElement = tempDiv;
2227
- const window = currentElement.ownerDocument.defaultView;
2242
+ function getElementFromXPath(docmt, xpath) {
2243
+ const window = docmt.defaultView;
2228
2244
  if (!window)
2229
2245
  return null;
2230
2246
  const xpathEvaluator = new window.XPathEvaluator();
2231
- const xpathResult = xpathEvaluator.evaluate(xpath, currentElement.ownerDocument, //here even tempDiv can be passed
2232
- null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2247
+ const xpathResult = xpathEvaluator.evaluate(xpath, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2233
2248
  return xpathResult.singleNodeValue;
2234
2249
  }
2235
- function checkReferenceElementIsValid(locator, relation, tempDiv) {
2250
+ function checkReferenceElementIsValid(locator, relation, docmt) {
2236
2251
  if (locator.includes(relation)) {
2237
2252
  const locatotSplitArray = locator.split(relation);
2238
2253
  const sourceLoc = locatotSplitArray[0].trim();
2239
- let currentElement = tempDiv;
2240
- const window = currentElement.ownerDocument.defaultView;
2254
+ const window = docmt.defaultView;
2241
2255
  if (!window)
2242
2256
  return null;
2243
2257
  if (!locator.includes("dynamic")) {
2244
2258
  const xpathEvaluator = new window.XPathEvaluator();
2245
- const xpathResult = xpathEvaluator.evaluate(sourceLoc, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2259
+ const xpathResult = xpathEvaluator.evaluate(sourceLoc, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2246
2260
  const sourceElement = xpathResult.singleNodeValue;
2247
2261
  if (sourceElement) {
2248
- const xpathResultComplete = xpathEvaluator.evaluate(locator, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2262
+ const xpathResultComplete = xpathEvaluator.evaluate(locator, docmt, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
2249
2263
  const completeElement = xpathResultComplete.singleNodeValue;
2250
2264
  let relativeXpath;
2251
2265
  if (completeElement) {
@@ -2266,16 +2280,12 @@ function checkReferenceElementIsValid(locator, relation, tempDiv) {
2266
2280
  return null;
2267
2281
  }
2268
2282
  const getElementsFromHTML = (record, docmt) => {
2269
- const document = docmt;
2270
- // global.SVGElement = document.defaultView?.SVGElement!;
2271
- const tempDiv = document.createElement("div");
2272
- const elementsToRemove = document.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
2283
+ const elementsToRemove = docmt.querySelectorAll("script, style, link[rel='stylesheet'], meta, noscript, embed, object, param, source, svg");
2273
2284
  if (elementsToRemove) {
2274
2285
  elementsToRemove.forEach((tag) => {
2275
2286
  tag.remove();
2276
2287
  });
2277
2288
  }
2278
- tempDiv.innerHTML = document.body?.innerHTML;
2279
2289
  const finalLocatorsSet = new Set();
2280
2290
  let finalLocators = [];
2281
2291
  function createLocator(base, overrides = {}) {
@@ -2349,135 +2359,126 @@ const getElementsFromHTML = (record, docmt) => {
2349
2359
  if (record.isShared.includes("Y")) {
2350
2360
  break locators;
2351
2361
  }
2352
- for (const relation of relations) {
2353
- try {
2354
- let targetElement = null;
2355
- if (locator.value.startsWith("iframe")) {
2356
- const iframe = tempDiv.querySelector(locator.value);
2357
- if (iframe) {
2358
- const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
2359
- if (iframeDocument) {
2360
- targetElement = iframeDocument.querySelector(locator.value.slice(6));
2361
- }
2362
+ try {
2363
+ let targetElement = null;
2364
+ if (locator.value.startsWith("iframe")) {
2365
+ const iframe = docmt.querySelector(locator.value);
2366
+ if (iframe) {
2367
+ const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
2368
+ if (iframeDocument) {
2369
+ targetElement = iframeDocument.querySelector(locator.value.slice(6));
2362
2370
  }
2363
2371
  }
2364
- else {
2365
- const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
2366
- let currentElement = tempDiv;
2367
- for (const selector of selectors) {
2368
- if (currentElement) {
2369
- const trimmedSelector = selector.trim();
2370
- if (locator.name.includes("id") ||
2371
- trimmedSelector.startsWith("#")) {
2372
- targetElement = currentElement.querySelector("#" + trimmedSelector);
2373
- }
2374
- else if (locator.name.includes("className") ||
2375
- trimmedSelector.startsWith(".")) {
2376
- targetElement = currentElement.querySelector("." + trimmedSelector);
2377
- }
2378
- else if ((locator.name.includes("xpath") ||
2379
- trimmedSelector.startsWith("//")) &&
2380
- !locator.type.match("dynamic")) {
2381
- if (tempDiv?.innerHTML) {
2382
- const normalizedXPath = normalizeXPath(trimmedSelector);
2383
- targetElement = getElementFromXPath(tempDiv, normalizedXPath);
2384
- if (targetElement) {
2385
- createLocator(locator, {
2386
- value: trimmedSelector,
2387
- isRecorded: String(locator.isRecorded).includes("N")
2388
- ? "N"
2389
- : "Y",
2390
- });
2391
- }
2392
- }
2393
- }
2394
- else {
2395
- targetElement = currentElement.querySelector(trimmedSelector);
2396
- if (!targetElement) {
2397
- targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
2398
- }
2399
- }
2400
- if (!targetElement &&
2401
- isSvg(currentElement) &&
2402
- !locator.type.match("dynamic")) {
2403
- targetElement = currentElement.querySelector(trimmedSelector);
2372
+ }
2373
+ else {
2374
+ const selectors = locator.value.split(">>>"); // Custom delimiter for shadow DOM
2375
+ for (const selector of selectors) {
2376
+ if (docmt) {
2377
+ const trimmedSelector = selector.trim();
2378
+ if (locator.name.includes("id") ||
2379
+ trimmedSelector.startsWith("#")) {
2380
+ targetElement = docmt.querySelector("#" + trimmedSelector);
2381
+ }
2382
+ else if (locator.name.includes("className") ||
2383
+ trimmedSelector.startsWith(".")) {
2384
+ targetElement = docmt.querySelector("." + trimmedSelector);
2385
+ }
2386
+ else if ((locator.name.includes("xpath") ||
2387
+ trimmedSelector.startsWith("//")) &&
2388
+ !locator.type.match("dynamic")) {
2389
+ const normalizedXPath = normalizeXPath(trimmedSelector);
2390
+ targetElement = getElementFromXPath(docmt, normalizedXPath);
2391
+ if (targetElement) {
2392
+ createLocator(locator, {
2393
+ value: trimmedSelector,
2394
+ isRecorded: String(locator.isRecorded).includes("N")
2395
+ ? "N"
2396
+ : "Y",
2397
+ });
2404
2398
  }
2405
- currentElement = targetElement;
2406
2399
  }
2407
2400
  else {
2408
- console.error("Element not found at:", selector);
2409
- break;
2401
+ targetElement = docmt.querySelector(trimmedSelector);
2402
+ if (!targetElement) {
2403
+ targetElement = getElementFromShadowRoot(docmt.body, trimmedSelector);
2404
+ }
2410
2405
  }
2411
2406
  }
2407
+ else {
2408
+ console.error("Element not found at:", selector);
2409
+ break;
2410
+ }
2412
2411
  }
2413
- const locatorExists = (name, value) => {
2414
- const key = `${name}:${value}`;
2415
- return finalLocatorsSet.has(key);
2416
- };
2417
- if (targetElement) {
2418
- const idValue = getId(targetElement);
2419
- if (idValue && !locatorExists("id", idValue)) {
2420
- record.locators.forEach((loc) => {
2421
- createLocator(loc, {
2422
- name: "id",
2423
- value: idValue,
2424
- isRecorded: loc.value === idValue && loc.name === "id"
2425
- ? loc.isRecorded
2426
- : "Y",
2427
- isSelfHealed: loc.value === idValue && loc.name === "id"
2428
- ? loc.isSelfHealed
2429
- : "Y",
2430
- });
2412
+ }
2413
+ const locatorExists = (name, value) => {
2414
+ const key = `${name}:${value}`;
2415
+ return finalLocatorsSet.has(key);
2416
+ };
2417
+ if (targetElement) {
2418
+ const idValue = getId(targetElement);
2419
+ if (idValue && !locatorExists("id", idValue)) {
2420
+ record.locators.forEach((loc) => {
2421
+ createLocator(loc, {
2422
+ name: "id",
2423
+ value: idValue,
2424
+ isRecorded: loc.value === idValue && loc.name === "id"
2425
+ ? loc.isRecorded
2426
+ : "Y",
2427
+ isSelfHealed: loc.value === idValue && loc.name === "id"
2428
+ ? loc.isSelfHealed
2429
+ : "Y",
2431
2430
  });
2432
- }
2433
- const textValue = getVisibleText(targetElement);
2434
- if (textValue) {
2435
- record.locators.forEach((loc) => {
2436
- createLocator(loc, {
2437
- name: "linkText",
2438
- type: "static",
2439
- value: textValue,
2440
- isRecorded: loc.value === textValue ? loc.isRecorded : "Y",
2441
- isSelfHealed: loc.value === textValue ? loc.isSelfHealed : "Y",
2442
- });
2431
+ });
2432
+ }
2433
+ const textValue = getVisibleText(targetElement);
2434
+ if (textValue) {
2435
+ record.locators.forEach((loc) => {
2436
+ createLocator(loc, {
2437
+ name: "linkText",
2438
+ type: "static",
2439
+ value: textValue,
2440
+ isRecorded: loc.value === textValue ? loc.isRecorded : "Y",
2441
+ isSelfHealed: loc.value === textValue ? loc.isSelfHealed : "Y",
2443
2442
  });
2444
- }
2445
- const nameLocator = getName(targetElement);
2446
- if (nameLocator && !locatorExists("name", nameLocator)) {
2447
- record.locators.forEach((loc) => {
2448
- createLocator(loc, {
2449
- name: "name",
2450
- type: "static",
2451
- value: nameLocator,
2452
- isRecorded: loc.value === nameLocator && loc.name === "name"
2453
- ? loc.isRecorded
2454
- : "Y",
2455
- isSelfHealed: loc.value === nameLocator && loc.name === "name"
2456
- ? loc.isSelfHealed
2457
- : "Y",
2458
- });
2443
+ });
2444
+ }
2445
+ const nameLocator = getName(targetElement);
2446
+ if (nameLocator && !locatorExists("name", nameLocator)) {
2447
+ record.locators.forEach((loc) => {
2448
+ createLocator(loc, {
2449
+ name: "name",
2450
+ type: "static",
2451
+ value: nameLocator,
2452
+ isRecorded: loc.value === nameLocator && loc.name === "name"
2453
+ ? loc.isRecorded
2454
+ : "Y",
2455
+ isSelfHealed: loc.value === nameLocator && loc.name === "name"
2456
+ ? loc.isSelfHealed
2457
+ : "Y",
2459
2458
  });
2460
- }
2461
- const classValue = getClassName(targetElement);
2462
- if (classValue &&
2463
- classValue.trim() !== "" &&
2464
- !locatorExists("className", classValue)) {
2465
- record.locators.forEach((loc) => {
2466
- createLocator(loc, {
2467
- name: "className",
2468
- value: classValue,
2469
- isRecorded: loc.value === classValue && loc.name === "className"
2470
- ? loc.isRecorded
2471
- : "Y",
2472
- isSelfHealed: loc.value === classValue && loc.name === "className"
2473
- ? loc.isSelfHealed
2474
- : "Y",
2475
- });
2459
+ });
2460
+ }
2461
+ const classValue = getClassName(targetElement);
2462
+ if (classValue &&
2463
+ classValue.trim() !== "" &&
2464
+ !locatorExists("className", classValue)) {
2465
+ record.locators.forEach((loc) => {
2466
+ createLocator(loc, {
2467
+ name: "className",
2468
+ value: classValue,
2469
+ isRecorded: loc.value === classValue && loc.name === "className"
2470
+ ? loc.isRecorded
2471
+ : "Y",
2472
+ isSelfHealed: loc.value === classValue && loc.name === "className"
2473
+ ? loc.isSelfHealed
2474
+ : "Y",
2476
2475
  });
2477
- }
2478
- const xpathResults = parseDOM(targetElement, document, false, true);
2479
- xpathResults.forEach((result) => {
2480
- const fnValue = result.value;
2476
+ });
2477
+ }
2478
+ const xpathResults = parseDOM(targetElement, docmt, false, true);
2479
+ xpathResults.forEach((result) => {
2480
+ const fnValue = result.value;
2481
+ if (fnValue && !locatorExists(result.key.replace('xpath by', '').trim(), fnValue)) {
2481
2482
  record.locators.forEach((loc) => {
2482
2483
  createLocator(loc, {
2483
2484
  name: 'xpath',
@@ -2486,71 +2487,71 @@ const getElementsFromHTML = (record, docmt) => {
2486
2487
  isSelfHealed: loc.value === fnValue ? loc.isSelfHealed : 'Y',
2487
2488
  });
2488
2489
  });
2489
- });
2490
- for (const locator of record.locators) {
2491
- try {
2492
- for (const loc of record.locators) {
2493
- if (!loc.value)
2494
- continue;
2495
- for (const relation of relations) {
2496
- if (loc.value.includes(relation)) {
2497
- const relativeXpath = checkReferenceElementIsValid(loc.value, relation, tempDiv);
2498
- if (relativeXpath) {
2499
- createLocator(loc, {
2500
- name: "xpath",
2501
- value: relativeXpath,
2502
- isRecorded: locator.isRecorded !== "" &&
2503
- locator.isRecorded !== null
2504
- ? locator.isRecorded
2505
- : "Y",
2506
- });
2507
- break;
2508
- }
2490
+ }
2491
+ });
2492
+ for (const locator of record.locators) {
2493
+ try {
2494
+ for (const loc of record.locators) {
2495
+ if (!loc.value)
2496
+ continue;
2497
+ for (const relation of relations) {
2498
+ if (loc.value.includes(relation)) {
2499
+ const relativeXpath = checkReferenceElementIsValid(loc.value, relation, docmt);
2500
+ if (relativeXpath) {
2501
+ createLocator(loc, {
2502
+ name: "xpath",
2503
+ value: relativeXpath,
2504
+ isRecorded: locator.isRecorded !== "" &&
2505
+ locator.isRecorded !== null
2506
+ ? locator.isRecorded
2507
+ : "Y",
2508
+ });
2509
+ break;
2509
2510
  }
2510
2511
  }
2511
2512
  }
2512
2513
  }
2513
- catch (error) {
2514
- console.error("Error processing locator:", locator, error);
2515
- }
2516
2514
  }
2517
- const finalAutoHealedLocators = finalLocators.map((obj) => ({
2518
- ...obj,
2519
- value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
2520
- }));
2521
- const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
2522
- if (locator.value &&
2523
- !unique.some((l) => l.value === locator.value)) {
2524
- unique.push(locator);
2525
- }
2526
- return unique;
2527
- }, []);
2528
- const jsonResult = [
2529
- {
2530
- name: `${record.name}`,
2531
- desc: `${record.desc}`,
2532
- type: `${record.type}`,
2533
- locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
2534
- isShared: `${record.isShared}`,
2535
- projectId: `${record.projectId}`,
2536
- projectType: `${record.projectType}`,
2537
- isRecorded: `${record.isRecorded}`,
2538
- folder: `${record.folder}`,
2539
- parentId: `${record.parentId}`,
2540
- parentName: `${record.parentName}`,
2541
- platform: `${record.platform}`,
2542
- licenseId: `${record.licenseId}`,
2543
- licenseType: `${record.licenseType}`,
2544
- userId: `${record.userId}`,
2545
- },
2546
- ];
2547
- return jsonResult;
2515
+ catch (error) {
2516
+ console.error("Error processing locator:", locator, error);
2517
+ }
2548
2518
  }
2519
+ const finalAutoHealedLocators = finalLocators.map((obj) => ({
2520
+ ...obj,
2521
+ value: cleanLocatorValue(obj.value, obj.name, obj.isRecorded),
2522
+ }));
2523
+ const finalUniqueAutoHealedLocators = finalAutoHealedLocators.reduce((unique, locator) => {
2524
+ if (locator.value &&
2525
+ !unique.some((l) => l.value === locator.value)) {
2526
+ unique.push(locator);
2527
+ }
2528
+ return unique;
2529
+ }, []);
2530
+ const jsonResult = [
2531
+ {
2532
+ name: `${record.name}`,
2533
+ desc: `${record.desc}`,
2534
+ type: `${record.type}`,
2535
+ locators: finalUniqueAutoHealedLocators.filter((locator) => locator?.value != null && locator.value !== ""),
2536
+ isShared: `${record.isShared}`,
2537
+ projectId: `${record.projectId}`,
2538
+ projectType: `${record.projectType}`,
2539
+ isRecorded: `${record.isRecorded}`,
2540
+ folder: `${record.folder}`,
2541
+ parentId: `${record.parentId}`,
2542
+ parentName: `${record.parentName}`,
2543
+ platform: `${record.platform}`,
2544
+ licenseId: `${record.licenseId}`,
2545
+ licenseType: `${record.licenseType}`,
2546
+ userId: `${record.userId}`,
2547
+ },
2548
+ ];
2549
+ return jsonResult;
2549
2550
  }
2550
- catch (error) {
2551
- console.error("Error processing locator:", locator, error);
2552
- continue;
2553
- }
2551
+ }
2552
+ catch (error) {
2553
+ console.error("Error processing locator:", locator, error);
2554
+ continue;
2554
2555
  }
2555
2556
  }
2556
2557
  catch (error) {