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.browser.cjs +197 -196
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.js +197 -196
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cdn.js +197 -196
- package/dist/types/browser/browser/xpath.d.ts +1 -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 +6 -5
- package/dist/xpath.mjs.map +1 -1
- package/package.json +1 -1
- package/src/node/xpath.ts +6 -5
- package/src/utils/getElementsFromHTML.ts +240 -240
- package/src/utils/xpathHelpers.ts +2 -2
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,
|
|
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 = (
|
|
2192
|
-
const shadowRoot = element.shadowRoot;
|
|
2193
|
-
if (shadowRoot && !selector.includes("dynamic")) {
|
|
2194
|
-
|
|
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(
|
|
2229
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
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
|
-
|
|
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
|
-
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
|
-
|
|
2412
|
-
|
|
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
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
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
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
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
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
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
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
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
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
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
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
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
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
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
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
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<
|
|
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
|
|
48
|
+
return await page?.evaluate((datum) => {
|
|
49
49
|
// @ts-ignore
|
|
50
50
|
let xpathAPI = window.XpathLib.createXPathAPI();
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
let xpaths = xpathAPI.getElementsFromHTML(datum, document);
|
|
52
|
+
// console.log(xpaths);
|
|
53
|
+
return xpaths;
|
|
54
|
+
}, data);
|
|
54
55
|
},
|
|
55
56
|
};
|
|
56
57
|
};
|
package/dist/xpath.mjs.map
CHANGED
|
@@ -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
|
|
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
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
|
|
62
|
+
return await page?.evaluate((datum: ElementRecord) => {
|
|
63
63
|
// @ts-ignore
|
|
64
64
|
let xpathAPI = window.XpathLib.createXPathAPI();
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
let xpaths = xpathAPI.getElementsFromHTML(datum, document);
|
|
66
|
+
// console.log(xpaths);
|
|
67
|
+
return xpaths;
|
|
68
|
+
}, data);
|
|
68
69
|
},
|
|
69
70
|
};
|
|
70
71
|
};
|