From 01f338128911314a06985830ee0563bce82750f7 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Wed, 5 Jun 2024 10:42:00 +0530 Subject: [PATCH] feat: types for Node --- server/src/workflow-management/selector.ts | 131 ++++++++++++++++++++- 1 file changed, 129 insertions(+), 2 deletions(-) diff --git a/server/src/workflow-management/selector.ts b/server/src/workflow-management/selector.ts index b641aa8a..1a2400af 100644 --- a/server/src/workflow-management/selector.ts +++ b/server/src/workflow-management/selector.ts @@ -101,6 +101,22 @@ export const getElementInformation = async ( export const getSelectors = async (page: Page, coordinates: Coordinates) => { try { const selectors : any = await page.evaluate(async ({ x, y }) => { + // version @medv/finder + // https://github.com/antonmedv/finder/blob/master/finder.ts + + type Node = { + name: string; + penalty: number; + level?: number; + }; + + type Path = Node[]; + + enum Limit { + All, + Two, + One, + } type Options = { root: Element; @@ -114,9 +130,12 @@ export const getSelectors = async (page: Page, coordinates: Coordinates) => { maxNumberOfTries: number; }; + let config: Options; + + let rootDocument: Document | Element; function finder(input: Element, options?: Partial) { - + const defaults: Options = { root: document.body, idName: (name: string) => true, @@ -129,6 +148,11 @@ export const getSelectors = async (page: Page, coordinates: Coordinates) => { maxNumberOfTries: 10000, }; + config = { ...defaults, ...options }; + + rootDocument = findRootDocument(config.root, defaults); + + } function findRootDocument(rootNode: Element | Document, defaults: Options) { @@ -141,7 +165,110 @@ export const getSelectors = async (page: Page, coordinates: Coordinates) => { return rootNode; } -} + function bottomUpSearch( + input: Element, + limit: Limit, + fallback?: () => Path | null + ): Path | null { + let path: Path | null = null; + let stack: Node[][] = []; + let current: Element | null = input; + let i = 0; + + while (current && current !== config.root.parentElement) { + let level: Node[] = maybe(id(current)) || + maybe(...attr(current)) || + maybe(...classNames(current)) || + maybe(tagName(current)) || [any()]; + + const nth = index(current); + + if (limit === Limit.All) { + if (nth) { + level = level.concat( + level.filter(dispensableNth).map((node) => nthChild(node, nth)) + ); + } + } else if (limit === Limit.Two) { + level = level.slice(0, 1); + + if (nth) { + level = level.concat( + level.filter(dispensableNth).map((node) => nthChild(node, nth)) + ); + } + } else if (limit === Limit.One) { + const [node] = (level = level.slice(0, 1)); + + if (nth && dispensableNth(node)) { + level = [nthChild(node, nth)]; + } + } + + for (let node of level) { + node.level = i; + } + + stack.push(level); + + if (stack.length >= config.seedMinLength) { + path = findUniquePath(stack, fallback); + if (path) { + break; + } + } + + current = current.parentElement; + i++; + } + + if (!path) { + path = findUniquePath(stack, fallback); + } + + return path; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +}; + + +