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