ff-dom 1.0.17 → 1.0.18-beta.1

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.
@@ -0,0 +1,110 @@
1
+ export declare const createXPathAPI: () => {
2
+ xpath: {
3
+ parseDOM: (element: HTMLElement | Element, doc: Document, isIndex: boolean, isTarget: boolean) => {
4
+ key: string;
5
+ value: string;
6
+ }[];
7
+ getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
8
+ getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
9
+ attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
10
+ addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => void;
11
+ addRelativeXpaths: (targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean, attribute: Attr[]) => {
12
+ key: string;
13
+ value: string;
14
+ }[] | undefined;
15
+ getXPathUsingAttributeAndText: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isTarget: boolean) => string | undefined;
16
+ getSiblingRelativeXPath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean, nodeXpath: string) => null | undefined;
17
+ getChildRelativeXpath: (domNode: HTMLElement | Element, docmt: Document, node: HTMLElement | Element) => string | null;
18
+ getParentRelativeXpath: (domNode: HTMLElement, docmt: Document, node: HTMLElement | Element, isTarget: boolean) => any;
19
+ getUniqueParentXpath: (domNode: HTMLElement, docmt: Document, node: HTMLElement | Element, isTarget: boolean, nodeXpath: string, isIndex: boolean) => any;
20
+ checkRelativeXpathRelation: (nodeXpath1: string, nodeXpath2: string, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, relationType: string) => string | null;
21
+ };
22
+ referenceXpaths: {
23
+ findRelativeXpath: (element1: HTMLElement | Element, element2: HTMLElement | Element, docmt: Document, xpaths1: any[], xpaths2: any[], isIndex: any) => any[] | undefined;
24
+ getDescendantXpath: (refExpectElement: Array<HTMLElement | Element>, docmt: Document, xpaths1: {
25
+ key: string;
26
+ value: string;
27
+ }[], xpaths2: {
28
+ key: string;
29
+ value: string;
30
+ }[], relation: "descendant" | "descedant-or-self", isIndex: boolean) => {
31
+ key: string;
32
+ value: string;
33
+ }[] | undefined;
34
+ getXpathRelationExpression: (element1: HTMLElement | Element, element2: HTMLElement | Element, relation: string, xpath1: any[], xpath2: any[], isIndex: any) => {
35
+ key: string;
36
+ value: any;
37
+ }[];
38
+ getTraverseXpathExpression: (xpathe1: string, absoluteXpathElements: any[], element2: HTMLElement | Element, refExpectElement: Array<HTMLElement | Element>, docmt: Node, relation: string, isIndex: any) => {
39
+ key: string;
40
+ value: string;
41
+ }[] | undefined;
42
+ getReferenceElementXpath: (element: HTMLElement | Element) => {
43
+ key: string;
44
+ value: string;
45
+ }[];
46
+ };
47
+ xpathUtils: {
48
+ parseXml: typeof import("../utils/xpathHelpers.ts").parseXml;
49
+ getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
50
+ key: string;
51
+ value: string;
52
+ }[];
53
+ getAbsoluteXPath: (domNode: HTMLElement | Element | null, docmt: Document) => string;
54
+ getRelativeXPath: (domNode: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean | undefined, attributesArray: Attr[]) => any;
55
+ getCombinationXpath: (attribute: Attr, domNode: HTMLElement | Element) => string | undefined;
56
+ getAttributeCombinationXpath: (domNode: HTMLElement | Element, docmt: Document, uniqueAttributes: Attr[], isTarget: boolean) => string | undefined;
57
+ getElementFromXpath: (xpath: string, docmt: Node, multi?: boolean) => Node | XPathResult | null;
58
+ isSvg: (element: HTMLElement | Element) => element is SVGElement;
59
+ findXpathWithIndex: (val: string, node: HTMLElement | Element, docmt: Node, count: number) => string | undefined;
60
+ isNumberExist: (str: string) => boolean;
61
+ getTextContent: (targetElement: HTMLElement | Element) => string;
62
+ getCountOfXPath: (xpath: string, element: HTMLElement | Element, docmt: Node) => number;
63
+ normalizeXPath: (xpath: string) => string;
64
+ getShadowRoot: (a: HTMLElement | Element) => Element | null;
65
+ escapeCharacters: (text: string) => string;
66
+ removeParenthesis: (xpath: string) => string;
67
+ checkBlockedAttributes: (attribute: {
68
+ name: string;
69
+ value: string;
70
+ }, targetElement: HTMLElement | Element, isTarget: boolean) => boolean;
71
+ getRelationship: (a: HTMLElement, b: HTMLElement) => "" | "preceding" | "following" | "ancestor" | "descendant" | "self";
72
+ findMatchingParenthesis: (text: string, openPos: number) => number;
73
+ deleteGarbageFromInnerText: (a: string) => string;
74
+ replaceTempAttributes: (str: string) => string;
75
+ createObserver: (addedNodeCallBack: Function) => void;
76
+ startObserver: (target: Node, options: MutationObserverInit | undefined) => void;
77
+ stopObserver: () => void;
78
+ modifiedElementAttributes: {
79
+ url: string | null;
80
+ attributeName: string | null;
81
+ element: HTMLElement | Element;
82
+ doc: Document;
83
+ }[];
84
+ };
85
+ getElementsFromHTML: (record: import("../types/locator.ts").ElementRecord, docmt: Document) => {
86
+ [key: string]: any;
87
+ id?: string | null;
88
+ className?: string | null;
89
+ xpathByText?: string | null;
90
+ xpathById?: string | null;
91
+ xpathByClass?: string | null;
92
+ xpathAbsolute?: string | null;
93
+ xpathByName?: string | null;
94
+ xpathByPlaceholder?: string | null;
95
+ xpathByType?: string | null;
96
+ visibleText?: string | null;
97
+ relativeXpath?: string | null;
98
+ } | null;
99
+ cssSelectors: {
100
+ parseCssSelectors: (el: HTMLElement | Element, docmt: Document) => {
101
+ key: string;
102
+ value: string;
103
+ }[];
104
+ getIdCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
105
+ getNameCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
106
+ getClassCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
107
+ getAbsoluteCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
108
+ };
109
+ };
110
+ export default createXPathAPI;
@@ -0,0 +1,26 @@
1
+ export interface Locator {
2
+ name: string;
3
+ type: string;
4
+ value: string;
5
+ reference: string;
6
+ status: string;
7
+ isRecorded: string;
8
+ isSelfHealed?: string;
9
+ }
10
+ export interface ElementRecord {
11
+ name: string;
12
+ desc: string;
13
+ type: string;
14
+ locators: Locator[];
15
+ isShared: string;
16
+ projectId: string;
17
+ projectType: string;
18
+ isRecorded: string;
19
+ folder: string;
20
+ parentId: string;
21
+ parentName: string;
22
+ platform: string;
23
+ licenseId: string;
24
+ licenseType: string;
25
+ userId: string;
26
+ }
@@ -0,0 +1,18 @@
1
+ export declare const parseCssSelectors: (el: HTMLElement | Element, docmt: Document) => {
2
+ key: string;
3
+ value: string;
4
+ }[];
5
+ export declare const getIdCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
6
+ export declare const getNameCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
7
+ export declare const getClassCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
8
+ export declare const getAbsoluteCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
9
+ export declare const cssSelectors: {
10
+ parseCssSelectors: (el: HTMLElement | Element, docmt: Document) => {
11
+ key: string;
12
+ value: string;
13
+ }[];
14
+ getIdCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
15
+ getNameCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
16
+ getClassCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
17
+ getAbsoluteCssPath: (el: HTMLElement | Element, docmt: Document) => string | undefined;
18
+ };
@@ -0,0 +1,17 @@
1
+ import { ElementRecord } from "../types/locator.ts";
2
+ type ElementDetails = {
3
+ id?: string | null;
4
+ className?: string | null;
5
+ xpathByText?: string | null;
6
+ xpathById?: string | null;
7
+ xpathByClass?: string | null;
8
+ xpathAbsolute?: string | null;
9
+ xpathByName?: string | null;
10
+ xpathByPlaceholder?: string | null;
11
+ xpathByType?: string | null;
12
+ visibleText?: string | null;
13
+ relativeXpath?: string | null;
14
+ [key: string]: any;
15
+ };
16
+ declare const getElementsFromHTML: (record: ElementRecord, docmt: Document) => ElementDetails | null;
17
+ export { getElementsFromHTML };
@@ -0,0 +1,27 @@
1
+ export declare const findRelativeXpath: (element1: HTMLElement | Element, element2: HTMLElement | Element, docmt: Document, xpaths1: any[], xpaths2: any[], isIndex: any) => any[] | undefined;
2
+ declare const referenceXpath: {
3
+ findRelativeXpath: (element1: HTMLElement | Element, element2: HTMLElement | Element, docmt: Document, xpaths1: any[], xpaths2: any[], isIndex: any) => any[] | undefined;
4
+ getDescendantXpath: (refExpectElement: Array<HTMLElement | Element>, docmt: Document, xpaths1: {
5
+ key: string;
6
+ value: string;
7
+ }[], xpaths2: {
8
+ key: string;
9
+ value: string;
10
+ }[], relation: "descendant" | "descedant-or-self", isIndex: boolean) => {
11
+ key: string;
12
+ value: string;
13
+ }[] | undefined;
14
+ getXpathRelationExpression: (element1: HTMLElement | Element, element2: HTMLElement | Element, relation: string, xpath1: any[], xpath2: any[], isIndex: any) => {
15
+ key: string;
16
+ value: any;
17
+ }[];
18
+ getTraverseXpathExpression: (xpathe1: string, absoluteXpathElements: any[], element2: HTMLElement | Element, refExpectElement: Array<HTMLElement | Element>, docmt: Node, relation: string, isIndex: any) => {
19
+ key: string;
20
+ value: string;
21
+ }[] | undefined;
22
+ getReferenceElementXpath: (element: HTMLElement | Element) => {
23
+ key: string;
24
+ value: string;
25
+ }[];
26
+ };
27
+ export default referenceXpath;
@@ -0,0 +1,29 @@
1
+ declare function getXPathUsingAttributeAndText(attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isTarget: boolean): string | undefined;
2
+ export declare const attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
3
+ export declare const getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
4
+ export declare const getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
5
+ export declare const parseDOM: (element: HTMLElement | Element, doc: Document, isIndex: boolean, isTarget: boolean) => {
6
+ key: string;
7
+ value: string;
8
+ }[];
9
+ declare const xpath: {
10
+ parseDOM: (element: HTMLElement | Element, doc: Document, isIndex: boolean, isTarget: boolean) => {
11
+ key: string;
12
+ value: string;
13
+ }[];
14
+ getTextXPath: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
15
+ getUniqueClassName: (element: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
16
+ attributesBasedXPath: (attr: Attr, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => string | undefined;
17
+ addAllXPathAttributes: (attributes: Attr[], targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean) => void;
18
+ addRelativeXpaths: (targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean, attribute: Attr[]) => {
19
+ key: string;
20
+ value: string;
21
+ }[] | undefined;
22
+ getXPathUsingAttributeAndText: typeof getXPathUsingAttributeAndText;
23
+ getSiblingRelativeXPath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean, nodeXpath: string) => null | undefined;
24
+ getChildRelativeXpath: (domNode: HTMLElement | Element, docmt: Document, node: HTMLElement | Element) => string | null;
25
+ getParentRelativeXpath: (domNode: HTMLElement, docmt: Document, node: HTMLElement | Element, isTarget: boolean) => any;
26
+ getUniqueParentXpath: (domNode: HTMLElement, docmt: Document, node: HTMLElement | Element, isTarget: boolean, nodeXpath: string, isIndex: boolean) => any;
27
+ checkRelativeXpathRelation: (nodeXpath1: string, nodeXpath2: string, targetElemt: HTMLElement | Element, docmt: Document, isIndex: boolean, relationType: string) => string | null;
28
+ };
29
+ export default xpath;
@@ -0,0 +1,88 @@
1
+ export declare const reWhiteSpace: RegExp;
2
+ export declare let modifiedElementAttributes: {
3
+ url: string | null;
4
+ attributeName: string | null;
5
+ element: HTMLElement | Element;
6
+ doc: Document;
7
+ }[];
8
+ export declare const createObserver: (addedNodeCallBack: Function) => void;
9
+ export declare const startObserver: (target: Node, options: MutationObserverInit | undefined) => void;
10
+ export declare const stopObserver: () => void;
11
+ export declare const isNumberExist: (str: string) => boolean;
12
+ export declare const buildPattern: (pattern: string, isSvg: boolean, tagName: string) => string;
13
+ export declare const getTextContent: (targetElement: HTMLElement | Element) => string;
14
+ export declare const getFilteredText: (element: Node) => string;
15
+ export declare const getCountOfXPath: (xpath: string, element: HTMLElement | Element, docmt: Node) => number;
16
+ export declare const escapeCharacters: (text: string) => string;
17
+ export declare const removeParenthesis: (xpath: string) => string;
18
+ export declare const findXpathWithIndex: (val: string, node: HTMLElement | Element, docmt: Node, count: number) => string | undefined;
19
+ export declare const replaceWhiteSpaces: (str: string) => string;
20
+ export declare const getShadowRoot: (a: HTMLElement | Element) => Element | null;
21
+ export declare const checkBlockedAttributes: (attribute: {
22
+ name: string;
23
+ value: string;
24
+ }, targetElement: HTMLElement | Element, isTarget: boolean) => boolean;
25
+ export declare const getRelationship: (a: HTMLElement, b: HTMLElement) => "" | "preceding" | "following" | "ancestor" | "descendant" | "self";
26
+ export declare const findRoot: (node: Node) => Node;
27
+ export declare const isSvg: (element: HTMLElement | Element) => element is SVGElement;
28
+ export declare const replaceTempAttributes: (str: string) => string;
29
+ export declare const getPropertyXPath: (element: HTMLElement | Element, docmt: Document, prop: string, value: string, isIndex: boolean, isTarget: boolean) => string | undefined;
30
+ export declare const getAbsoluteXPath: (domNode: HTMLElement | Element | null, docmt: Document) => string;
31
+ export declare const getRelativeXPath: (domNode: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean | undefined, attributesArray: Attr[]) => any;
32
+ export declare const getCombinationXpath: (attribute: Attr, domNode: HTMLElement | Element) => string | undefined;
33
+ export declare const getAttributeCombinationXpath: (domNode: HTMLElement | Element, docmt: Document, uniqueAttributes: Attr[], isTarget: boolean) => string | undefined;
34
+ export declare const intermediateXpathStep: (targetElemt: HTMLElement | Element, attr: {
35
+ name: string;
36
+ value: string;
37
+ }, isTarget: boolean) => string;
38
+ export declare const getFilteredTextXPath: (node: HTMLElement | Element, docmt: Document) => string;
39
+ export declare const getTextXpathFunction: (domNode: HTMLElement | Element) => string | undefined;
40
+ export declare const getXpathString: (node: HTMLElement | Element, attrName: string, attrValue: string) => string;
41
+ export declare const replaceActualAttributes: (str: string, element: {
42
+ attributes: any;
43
+ }) => string;
44
+ export declare const getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
45
+ key: string;
46
+ value: string;
47
+ }[];
48
+ export declare function parseXml(xmlStr: string): Document | null;
49
+ export declare const normalizeXPath: (xpath: string) => string;
50
+ export declare const findMatchingParenthesis: (text: string, openPos: number) => number;
51
+ export declare const xpathUtils: {
52
+ parseXml: typeof parseXml;
53
+ getReferenceElementsXpath: (domNode: HTMLElement | Element, docmt: Document, isTarget: boolean) => {
54
+ key: string;
55
+ value: string;
56
+ }[];
57
+ getAbsoluteXPath: (domNode: HTMLElement | Element | null, docmt: Document) => string;
58
+ getRelativeXPath: (domNode: HTMLElement | Element, docmt: Document, isIndex: boolean, isTarget: boolean | undefined, attributesArray: Attr[]) => any;
59
+ getCombinationXpath: (attribute: Attr, domNode: HTMLElement | Element) => string | undefined;
60
+ getAttributeCombinationXpath: (domNode: HTMLElement | Element, docmt: Document, uniqueAttributes: Attr[], isTarget: boolean) => string | undefined;
61
+ getElementFromXpath: (xpath: string, docmt: Node, multi?: boolean) => Node | XPathResult | null;
62
+ isSvg: (element: HTMLElement | Element) => element is SVGElement;
63
+ findXpathWithIndex: (val: string, node: HTMLElement | Element, docmt: Node, count: number) => string | undefined;
64
+ isNumberExist: (str: string) => boolean;
65
+ getTextContent: (targetElement: HTMLElement | Element) => string;
66
+ getCountOfXPath: (xpath: string, element: HTMLElement | Element, docmt: Node) => number;
67
+ normalizeXPath: (xpath: string) => string;
68
+ getShadowRoot: (a: HTMLElement | Element) => Element | null;
69
+ escapeCharacters: (text: string) => string;
70
+ removeParenthesis: (xpath: string) => string;
71
+ checkBlockedAttributes: (attribute: {
72
+ name: string;
73
+ value: string;
74
+ }, targetElement: HTMLElement | Element, isTarget: boolean) => boolean;
75
+ getRelationship: (a: HTMLElement, b: HTMLElement) => "" | "preceding" | "following" | "ancestor" | "descendant" | "self";
76
+ findMatchingParenthesis: (text: string, openPos: number) => number;
77
+ deleteGarbageFromInnerText: (a: string) => string;
78
+ replaceTempAttributes: (str: string) => string;
79
+ createObserver: (addedNodeCallBack: Function) => void;
80
+ startObserver: (target: Node, options: MutationObserverInit | undefined) => void;
81
+ stopObserver: () => void;
82
+ modifiedElementAttributes: {
83
+ url: string | null;
84
+ attributeName: string | null;
85
+ element: HTMLElement | Element;
86
+ doc: Document;
87
+ }[];
88
+ };
@@ -0,0 +1,8 @@
1
+ import { ElementRecord } from "../types/locator";
2
+ declare function createXPathAPI(): Promise<{
3
+ fromHTML: (html: string) => Promise<{
4
+ autoHeal: (data: ElementRecord, htmlString: string) => Promise<void>;
5
+ }>;
6
+ browser: any;
7
+ }>;
8
+ export default createXPathAPI;
@@ -0,0 +1,26 @@
1
+ export interface Locator {
2
+ name: string;
3
+ type: string;
4
+ value: string;
5
+ reference: string;
6
+ status: string;
7
+ isRecorded: string;
8
+ isSelfHealed?: string;
9
+ }
10
+ export interface ElementRecord {
11
+ name: string;
12
+ desc: string;
13
+ type: string;
14
+ locators: Locator[];
15
+ isShared: string;
16
+ projectId: string;
17
+ projectType: string;
18
+ isRecorded: string;
19
+ folder: string;
20
+ parentId: string;
21
+ parentName: string;
22
+ platform: string;
23
+ licenseId: string;
24
+ licenseType: string;
25
+ userId: string;
26
+ }
package/dist/xpath.mjs ADDED
@@ -0,0 +1,63 @@
1
+ import { fileURLToPath } from 'url';
2
+ import path, { join } from 'path';
3
+ import { readFileSync } from 'fs';
4
+
5
+ const _filename = fileURLToPath(import.meta.url);
6
+ const _dirname = path.dirname(_filename);
7
+ let puppeteer;
8
+ const injectScriptPath = join(_dirname, "index.cdn.js");
9
+ const injectScript = readFileSync(injectScriptPath, "utf-8");
10
+ async function createXPathAPI() {
11
+ puppeteer = await import('puppeteer');
12
+ let browser = await puppeteer.launch({ headless: true });
13
+ let page = await browser.newPage();
14
+ const fromHTML = async (html) => {
15
+ await page?.setContent(html);
16
+ await page?.addScriptTag({ content: injectScript });
17
+ page?.on("console", async (msg) => {
18
+ const type = msg.type();
19
+ const txt = msg.text();
20
+ const args = msg.args();
21
+ if (!args || args.length === 0) {
22
+ console.log(`[Browser:${type}]`, txt);
23
+ return;
24
+ }
25
+ for (let i = 0; i < args.length; i++) {
26
+ try {
27
+ const arg = args[i];
28
+ const obj = arg.remoteObject();
29
+ console.log(obj);
30
+ if (obj.value !== undefined) {
31
+ console.log(`[Browser:${type}]`, obj.value);
32
+ }
33
+ else {
34
+ const value = await arg.jsonValue().catch(() => txt);
35
+ console.log(`[Browser:${type}]`, value);
36
+ }
37
+ }
38
+ catch (err) {
39
+ console.log(`[Browser:${type}]`, txt);
40
+ }
41
+ }
42
+ });
43
+ page?.on("pageerror", (msg) => {
44
+ console.log("error", msg);
45
+ });
46
+ return {
47
+ autoHeal: async (data, htmlString) => {
48
+ await page?.evaluate((datum, html) => {
49
+ // let docmt = (window as any).XpathLib.parseXml(html);
50
+ // return (window as any).XpathLib.getElementsFromHTML(datum, docmt);
51
+ // @ts-ignore
52
+ let xpathAPI = window.XpathLib.createXPathAPI();
53
+ let docmt = xpathAPI.xpathUtils.parseXml(html);
54
+ return xpathAPI.getElementsFromHTML(datum, docmt);
55
+ }, data, htmlString);
56
+ },
57
+ };
58
+ };
59
+ return { fromHTML, browser };
60
+ }
61
+
62
+ export { createXPathAPI as default };
63
+ //# sourceMappingURL=xpath.mjs.map
@@ -0,0 +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, html: string) => {\r\n // let docmt = (window as any).XpathLib.parseXml(html);\r\n // return (window as any).XpathLib.getElementsFromHTML(datum, docmt);\r\n // @ts-ignore\r\n let xpathAPI = window.XpathLib.createXPathAPI();\r\n let docmt = xpathAPI.xpathUtils.parseXml(html);\r\n return xpathAPI.getElementsFromHTML(datum, docmt);\r\n }, data, htmlString);\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
@@ -1,21 +1,71 @@
1
1
  {
2
2
  "name": "ff-dom",
3
- "version": "1.0.17",
3
+ "version": "1.0.18-beta.1",
4
4
  "description": "",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
5
+ "type": "module",
6
+ "files": [
7
+ "dist",
8
+ "src",
9
+ "package.json",
10
+ "README.md",
11
+ "tsconfig.json",
12
+ "tsconfig.node.json",
13
+ "tsconfig.browser.json"
14
+ ],
15
+ "main": "dist/index.browser.cjs",
16
+ "module": "dist/index.browser.js",
17
+ "types": "dist/types/browser/browser/.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/types/browser/browser/xpath.d.ts",
21
+ "import": "./dist/index.browser.js",
22
+ "default": "./dist/index.browser.js",
23
+ "require": "./dist/index.browser.cjs"
24
+ },
25
+ "./node": {
26
+ "import": "./dist/xpath.mjs",
27
+ "default": "./dist/xpath.mjs",
28
+ "types": "./dist/types/node/xpath.d.ts"
29
+ }
30
+ },
31
+ "typesVersions": {
32
+ "*": {
33
+ "*": [
34
+ "dist/types/browser/xpath.d.ts"
35
+ ],
36
+ "node": [
37
+ "dist/types/node/xpath.d.ts"
38
+ ]
39
+ }
40
+ },
7
41
  "scripts": {
8
- "build": "tsc",
9
- "test": "echo \"Error: no test specified\" && exit 1"
42
+ "lint": "eslint --fix",
43
+ "build": "rimraf dist && npm run types && rollup -c",
44
+ "types:node": "tsc -p tsconfig.node.json --emitDeclarationOnly --outDir dist/types/node",
45
+ "types:browser": "tsc -p tsconfig.browser.json --emitDeclarationOnly --outDir dist/types/browser",
46
+ "types": "npm run types:node && npm run types:browser",
47
+ "test": "echo \"Error: no test specified\" && exit 1",
48
+ "test:node": "node test/node.spec.js",
49
+ "test:browser": "start test/browser.spec.js"
10
50
  },
11
51
  "keywords": [],
12
52
  "author": "",
13
53
  "license": "ISC",
14
54
  "dependencies": {
15
- "jsdom": "^25.0.1"
55
+ "puppeteer": "^24.30.0"
16
56
  },
17
57
  "devDependencies": {
18
- "@types/jsdom": "^21.1.7",
19
- "typescript": "^5.6.3"
58
+ "@rollup/plugin-commonjs": "^28.0.9",
59
+ "@rollup/plugin-dynamic-import-vars": "^2.1.5",
60
+ "@rollup/plugin-node-resolve": "^16.0.3",
61
+ "@rollup/plugin-terser": "^0.4.4",
62
+ "@rollup/plugin-typescript": "^12.1.4",
63
+ "@typescript-eslint/eslint-plugin": "^8.46.2",
64
+ "@typescript-eslint/parser": "^8.46.2",
65
+ "eslint": "^9.38.0",
66
+ "rimraf": "^6.1.0",
67
+ "rollup": "^4.52.4",
68
+ "tslib": "^2.8.1",
69
+ "typescript": "^5.9.3"
20
70
  }
21
71
  }
@@ -0,0 +1,15 @@
1
+ import xpath from '../utils/xpath.ts';
2
+ import referenceXpaths from '../utils/referenceXpath.ts';
3
+ import { xpathUtils } from '../utils/xpathHelpers.ts';
4
+ import { getElementsFromHTML } from '../utils/getElementsFromHTML.ts';
5
+ import { cssSelectors } from '../utils/cssSelector.ts';
6
+
7
+ export const createXPathAPI = () => ({
8
+ xpath,
9
+ referenceXpaths,
10
+ xpathUtils,
11
+ getElementsFromHTML,
12
+ cssSelectors
13
+ });
14
+
15
+ export default createXPathAPI;
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './node/xpath.ts';
2
+ export * from './browser/xpath.ts';
@@ -0,0 +1,9 @@
1
+ import createXPathAPI from '../browser/xpath';
2
+
3
+ declare global {
4
+ interface window {
5
+ XpathLib: typeof createXPathAPI
6
+ }
7
+ }
8
+
9
+ declare var puppeteer: any;
@@ -0,0 +1,75 @@
1
+ import { fileURLToPath } from "url";
2
+ import path, { join } from "path";
3
+ import { readFileSync } from "fs";
4
+ import { ElementRecord } from "../types/locator";
5
+
6
+ const _filename = fileURLToPath(import.meta.url);
7
+ const _dirname = path.dirname(_filename);
8
+
9
+ let puppeteer: any;
10
+
11
+ const injectScriptPath = join(_dirname, "index.cdn.js");
12
+ const injectScript = readFileSync(injectScriptPath, "utf-8");
13
+
14
+ async function createXPathAPI() {
15
+ puppeteer = await import('puppeteer');
16
+
17
+ let browser = await puppeteer.launch({ headless: true });
18
+ let page = await browser.newPage();
19
+
20
+ const fromHTML = async (html: string) => {
21
+ await page?.setContent(html);
22
+ await page?.addScriptTag({ content: injectScript });
23
+
24
+ page?.on(
25
+ "console",
26
+ async (msg: { type: () => any; text: () => any; args: () => any }) => {
27
+ const type = msg.type();
28
+ const txt = msg.text();
29
+
30
+ const args = msg.args();
31
+ if (!args || args.length === 0) {
32
+ console.log(`[Browser:${type}]`, txt);
33
+ return;
34
+ }
35
+
36
+ for (let i = 0; i < args.length; i++) {
37
+ try {
38
+ const arg = args[i];
39
+ const obj = arg.remoteObject();
40
+
41
+ console.log(obj);
42
+
43
+ if (obj.value !== undefined) {
44
+ console.log(`[Browser:${type}]`, obj.value);
45
+ } else {
46
+ const value = await arg.jsonValue().catch(() => txt);
47
+ console.log(`[Browser:${type}]`, value);
48
+ }
49
+ } catch (err) {
50
+ console.log(`[Browser:${type}]`, txt);
51
+ }
52
+ }
53
+ }
54
+ );
55
+
56
+ page?.on("pageerror", (msg: any) => {
57
+ console.log("error", msg);
58
+ });
59
+
60
+ return {
61
+ autoHeal: async (data: ElementRecord, htmlString: string) => {
62
+ await page?.evaluate((datum: ElementRecord, html: string) => {
63
+ // @ts-ignore
64
+ let xpathAPI = window.XpathLib.createXPathAPI();
65
+ let docmt = xpathAPI.xpathUtils.parseXml(html);
66
+ return xpathAPI.getElementsFromHTML(datum, docmt);
67
+ }, data, htmlString);
68
+ },
69
+ };
70
+ };
71
+
72
+ return { fromHTML, browser };
73
+ }
74
+
75
+ export default createXPathAPI;
@@ -0,0 +1,27 @@
1
+ export interface Locator {
2
+ name: string;
3
+ type: string;
4
+ value: string;
5
+ reference: string;
6
+ status: string;
7
+ isRecorded: string;
8
+ isSelfHealed?: string;
9
+ }
10
+
11
+ export interface ElementRecord {
12
+ name: string;
13
+ desc: string;
14
+ type: string;
15
+ locators: Locator[];
16
+ isShared: string;
17
+ projectId: string;
18
+ projectType: string;
19
+ isRecorded: string;
20
+ folder: string;
21
+ parentId: string;
22
+ parentName: string;
23
+ platform: string;
24
+ licenseId: string;
25
+ licenseType: string;
26
+ userId: string
27
+ }