ff-dom 1.0.2 → 1.0.3
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.
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getElementsFromHTML = void 0;
|
|
4
4
|
const jsdom_1 = require("jsdom");
|
|
5
|
+
const { stringify } = require("flatted");
|
|
5
6
|
const isUnique = (xpathResult) => {
|
|
6
7
|
return xpathResult && xpathResult.snapshotLength === 1;
|
|
7
8
|
};
|
|
8
9
|
const getElementFromShadowRoot = (element, selector) => {
|
|
9
10
|
const shadowRoot = element.shadowRoot;
|
|
10
|
-
if (shadowRoot) {
|
|
11
|
+
if (shadowRoot && !selector.includes("dynamic")) {
|
|
11
12
|
return shadowRoot.querySelector(selector);
|
|
12
13
|
}
|
|
13
14
|
return null;
|
|
@@ -135,26 +136,28 @@ function checkReferenceElementIsValid(locator, relation, tempDiv) {
|
|
|
135
136
|
const window = currentElement.ownerDocument.defaultView;
|
|
136
137
|
if (!window)
|
|
137
138
|
return null;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
if (!locator.includes("dynamic")) {
|
|
140
|
+
const xpathEvaluator = new window.XPathEvaluator();
|
|
141
|
+
const xpathResult = xpathEvaluator.evaluate(sourceLoc, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
142
|
+
const sourceElement = xpathResult.singleNodeValue;
|
|
143
|
+
if (sourceElement) {
|
|
144
|
+
const xpathResultComplete = xpathEvaluator.evaluate(locator, currentElement.ownerDocument, null, window.XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
145
|
+
const completeElement = xpathResultComplete.singleNodeValue;
|
|
146
|
+
let relativeXpath;
|
|
147
|
+
if (completeElement) {
|
|
148
|
+
relativeXpath = locator;
|
|
149
|
+
return relativeXpath;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.error("Complete Locator is Invalid:", locator);
|
|
153
|
+
relativeXpath = locator;
|
|
154
|
+
return relativeXpath;
|
|
155
|
+
}
|
|
148
156
|
}
|
|
149
157
|
else {
|
|
150
|
-
console.error("
|
|
151
|
-
relativeXpath = locator;
|
|
152
|
-
return relativeXpath;
|
|
158
|
+
console.error("Source Locator Not Found:", sourceLoc);
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
|
-
else {
|
|
156
|
-
console.error("Source Locator Not Found:", sourceLoc);
|
|
157
|
-
}
|
|
158
161
|
}
|
|
159
162
|
return null;
|
|
160
163
|
}
|
|
@@ -165,9 +168,40 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
165
168
|
const tempDiv = document.createElement("div");
|
|
166
169
|
tempDiv.innerHTML = htmlString;
|
|
167
170
|
let finalLocators = [];
|
|
168
|
-
for (const locator of locators) {
|
|
171
|
+
locators: for (const locator of locators) {
|
|
169
172
|
try {
|
|
170
173
|
let relativeXpath = null;
|
|
174
|
+
if (locator.value.includes("dynamic") ||
|
|
175
|
+
locator.type.match("dynamic") ||
|
|
176
|
+
locator.value.includes("{") ||
|
|
177
|
+
locator.value.includes("}")) {
|
|
178
|
+
console.log("Dynamic locator detected:", locator.value);
|
|
179
|
+
finalLocators.push({
|
|
180
|
+
name: locator.name,
|
|
181
|
+
type: locator.type,
|
|
182
|
+
value: locator.value,
|
|
183
|
+
reference: locator.reference,
|
|
184
|
+
status: locator.status,
|
|
185
|
+
isRecorded: locator.isRecorded,
|
|
186
|
+
});
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (locator.isRecorded.includes("N") || locator.isRecorded.match("N")) {
|
|
190
|
+
console.log("Manually added locator detected:", locator.value);
|
|
191
|
+
finalLocators.push({
|
|
192
|
+
name: locator.name,
|
|
193
|
+
type: locator.type,
|
|
194
|
+
value: locator.value,
|
|
195
|
+
reference: locator.reference,
|
|
196
|
+
status: locator.status,
|
|
197
|
+
isRecorded: locator.isRecorded,
|
|
198
|
+
});
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (isShared.includes("Y")) {
|
|
202
|
+
console.log("Shared element detected");
|
|
203
|
+
break locators;
|
|
204
|
+
}
|
|
171
205
|
for (const relation of relations) {
|
|
172
206
|
try {
|
|
173
207
|
let targetElement = null;
|
|
@@ -194,8 +228,9 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
194
228
|
trimmedSelector.startsWith(".")) {
|
|
195
229
|
targetElement = currentElement.querySelector("." + trimmedSelector);
|
|
196
230
|
}
|
|
197
|
-
else if (locator.name.includes("xpath") ||
|
|
198
|
-
trimmedSelector.startsWith("//"))
|
|
231
|
+
else if ((locator.name.includes("xpath") ||
|
|
232
|
+
trimmedSelector.startsWith("//")) &&
|
|
233
|
+
!locator.type.match("dynamic")) {
|
|
199
234
|
targetElement = getElementFromXPath(tempDiv, trimmedSelector);
|
|
200
235
|
}
|
|
201
236
|
else {
|
|
@@ -204,7 +239,9 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
204
239
|
targetElement = getElementFromShadowRoot(currentElement, trimmedSelector);
|
|
205
240
|
}
|
|
206
241
|
}
|
|
207
|
-
if (!targetElement &&
|
|
242
|
+
if (!targetElement &&
|
|
243
|
+
isSVGElement(currentElement) &&
|
|
244
|
+
!locator.type.match("dynamic")) {
|
|
208
245
|
targetElement = currentElement.querySelector(trimmedSelector);
|
|
209
246
|
}
|
|
210
247
|
currentElement = targetElement;
|
|
@@ -212,7 +249,10 @@ const getElementsFromHTML = (name, desc, type, locators, isShared, projectId, pr
|
|
|
212
249
|
}
|
|
213
250
|
}
|
|
214
251
|
const locatorExists = (name, value) => {
|
|
215
|
-
return finalLocators.some((loc) => loc.name === name &&
|
|
252
|
+
return finalLocators.some((loc) => loc.name === name &&
|
|
253
|
+
loc.value === value &&
|
|
254
|
+
(!loc.value.includes("dynamic") ||
|
|
255
|
+
!locator.type.match("dynamic")));
|
|
216
256
|
};
|
|
217
257
|
const xpathFunctions = [
|
|
218
258
|
{ name: "xpath", value: getXPathByText },
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JSDOM } from "jsdom";
|
|
2
|
+
const { stringify } = require("flatted");
|
|
2
3
|
|
|
3
4
|
type ElementDetails = {
|
|
4
5
|
id?: string | null;
|
|
@@ -24,7 +25,7 @@ const getElementFromShadowRoot = (
|
|
|
24
25
|
selector: string
|
|
25
26
|
): Element | null => {
|
|
26
27
|
const shadowRoot = (element as HTMLElement).shadowRoot;
|
|
27
|
-
if (shadowRoot) {
|
|
28
|
+
if (shadowRoot && !selector.includes("dynamic")) {
|
|
28
29
|
return shadowRoot.querySelector(selector);
|
|
29
30
|
}
|
|
30
31
|
return null;
|
|
@@ -195,37 +196,38 @@ function checkReferenceElementIsValid(
|
|
|
195
196
|
let currentElement: Element | null = tempDiv;
|
|
196
197
|
const window = currentElement.ownerDocument.defaultView;
|
|
197
198
|
if (!window) return null;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
currentElement.ownerDocument,
|
|
203
|
-
null,
|
|
204
|
-
window.XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
205
|
-
null
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const sourceElement = xpathResult.singleNodeValue;
|
|
209
|
-
if (sourceElement) {
|
|
210
|
-
const xpathResultComplete = xpathEvaluator.evaluate(
|
|
211
|
-
locator,
|
|
199
|
+
if (!locator.includes("dynamic")) {
|
|
200
|
+
const xpathEvaluator = new window.XPathEvaluator();
|
|
201
|
+
const xpathResult = xpathEvaluator.evaluate(
|
|
202
|
+
sourceLoc,
|
|
212
203
|
currentElement.ownerDocument,
|
|
213
204
|
null,
|
|
214
205
|
window.XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
215
206
|
null
|
|
216
207
|
);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
208
|
+
|
|
209
|
+
const sourceElement = xpathResult.singleNodeValue;
|
|
210
|
+
if (sourceElement) {
|
|
211
|
+
const xpathResultComplete = xpathEvaluator.evaluate(
|
|
212
|
+
locator,
|
|
213
|
+
currentElement.ownerDocument,
|
|
214
|
+
null,
|
|
215
|
+
window.XPathResult.FIRST_ORDERED_NODE_TYPE,
|
|
216
|
+
null
|
|
217
|
+
);
|
|
218
|
+
const completeElement = xpathResultComplete.singleNodeValue;
|
|
219
|
+
let relativeXpath: string;
|
|
220
|
+
if (completeElement) {
|
|
221
|
+
relativeXpath = locator;
|
|
222
|
+
return relativeXpath;
|
|
223
|
+
} else {
|
|
224
|
+
console.error("Complete Locator is Invalid:", locator);
|
|
225
|
+
relativeXpath = locator;
|
|
226
|
+
return relativeXpath;
|
|
227
|
+
}
|
|
222
228
|
} else {
|
|
223
|
-
console.error("
|
|
224
|
-
relativeXpath = locator;
|
|
225
|
-
return relativeXpath;
|
|
229
|
+
console.error("Source Locator Not Found:", sourceLoc);
|
|
226
230
|
}
|
|
227
|
-
} else {
|
|
228
|
-
console.error("Source Locator Not Found:", sourceLoc);
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
233
|
return null;
|
|
@@ -262,9 +264,42 @@ const getElementsFromHTML = (
|
|
|
262
264
|
tempDiv.innerHTML = htmlString;
|
|
263
265
|
let finalLocators = [];
|
|
264
266
|
|
|
265
|
-
for (const locator of locators) {
|
|
267
|
+
locators: for (const locator of locators) {
|
|
266
268
|
try {
|
|
267
269
|
let relativeXpath: string | null = null;
|
|
270
|
+
if (
|
|
271
|
+
locator.value.includes("dynamic") ||
|
|
272
|
+
locator.type.match("dynamic") ||
|
|
273
|
+
locator.value.includes("{") ||
|
|
274
|
+
locator.value.includes("}")
|
|
275
|
+
) {
|
|
276
|
+
console.log("Dynamic locator detected:", locator.value);
|
|
277
|
+
finalLocators.push({
|
|
278
|
+
name: locator.name,
|
|
279
|
+
type: locator.type,
|
|
280
|
+
value: locator.value,
|
|
281
|
+
reference: locator.reference,
|
|
282
|
+
status: locator.status,
|
|
283
|
+
isRecorded: locator.isRecorded,
|
|
284
|
+
});
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (locator.isRecorded.includes("N") || locator.isRecorded.match("N")) {
|
|
288
|
+
console.log("Manually added locator detected:", locator.value);
|
|
289
|
+
finalLocators.push({
|
|
290
|
+
name: locator.name,
|
|
291
|
+
type: locator.type,
|
|
292
|
+
value: locator.value,
|
|
293
|
+
reference: locator.reference,
|
|
294
|
+
status: locator.status,
|
|
295
|
+
isRecorded: locator.isRecorded,
|
|
296
|
+
});
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (isShared.includes("Y")) {
|
|
300
|
+
console.log("Shared element detected");
|
|
301
|
+
break locators;
|
|
302
|
+
}
|
|
268
303
|
for (const relation of relations) {
|
|
269
304
|
try {
|
|
270
305
|
let targetElement: Element | null = null;
|
|
@@ -303,8 +338,9 @@ const getElementsFromHTML = (
|
|
|
303
338
|
"." + trimmedSelector
|
|
304
339
|
);
|
|
305
340
|
} else if (
|
|
306
|
-
locator.name.includes("xpath") ||
|
|
307
|
-
|
|
341
|
+
(locator.name.includes("xpath") ||
|
|
342
|
+
trimmedSelector.startsWith("//")) &&
|
|
343
|
+
!locator.type.match("dynamic")
|
|
308
344
|
) {
|
|
309
345
|
targetElement = getElementFromXPath(tempDiv, trimmedSelector);
|
|
310
346
|
} else {
|
|
@@ -317,7 +353,11 @@ const getElementsFromHTML = (
|
|
|
317
353
|
}
|
|
318
354
|
}
|
|
319
355
|
|
|
320
|
-
if (
|
|
356
|
+
if (
|
|
357
|
+
!targetElement &&
|
|
358
|
+
isSVGElement(currentElement) &&
|
|
359
|
+
!locator.type.match("dynamic")
|
|
360
|
+
) {
|
|
321
361
|
targetElement = currentElement.querySelector(trimmedSelector);
|
|
322
362
|
}
|
|
323
363
|
|
|
@@ -328,7 +368,11 @@ const getElementsFromHTML = (
|
|
|
328
368
|
|
|
329
369
|
const locatorExists = (name: string, value: string) => {
|
|
330
370
|
return finalLocators.some(
|
|
331
|
-
(loc) =>
|
|
371
|
+
(loc) =>
|
|
372
|
+
loc.name === name &&
|
|
373
|
+
loc.value === value &&
|
|
374
|
+
(!loc.value.includes("dynamic") ||
|
|
375
|
+
!locator.type.match("dynamic"))
|
|
332
376
|
);
|
|
333
377
|
};
|
|
334
378
|
|