-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix: list selector highlighting #544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -302,59 +302,38 @@ export const getElementInformation = async ( | |
| ); | ||
| return elementInfo; | ||
| } else { | ||
| page.on('console', msg => { | ||
| console.log(`Browser console: ${msg.text()}`); | ||
| }); | ||
| const elementInfo = await page.evaluate( | ||
| async ({ x, y }) => { | ||
| const getDeepestElementFromPoint = (x: number, y: number): HTMLElement | null => { | ||
| let elements = document.elementsFromPoint(x, y) as HTMLElement[]; | ||
| if (!elements.length) return null; | ||
|
|
||
| const findDeepestElement = (elements: HTMLElement[]): HTMLElement | null => { | ||
| const findContainerElement = (elements: HTMLElement[]): HTMLElement | null => { | ||
| if (!elements.length) return null; | ||
| if (elements.length === 1) return elements[0]; | ||
|
|
||
| let deepestElement = elements[0]; | ||
| let maxDepth = 0; | ||
|
|
||
| for (const element of elements) { | ||
| let depth = 0; | ||
| let current = element; | ||
| for (let i = 0; i < elements.length; i++) { | ||
| const element = elements[i]; | ||
| const rect = element.getBoundingClientRect(); | ||
|
|
||
| while (current) { | ||
| depth++; | ||
| if (current.parentElement) { | ||
| current = current.parentElement; | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (depth > maxDepth) { | ||
| maxDepth = depth; | ||
| deepestElement = element; | ||
| if (rect.width >= 30 && rect.height >= 30) { | ||
| const hasChildrenInList = elements.some((otherElement, j) => | ||
| i !== j && element.contains(otherElement) | ||
| ); | ||
|
|
||
| if (hasChildrenInList) { | ||
| return element; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return deepestElement; | ||
| return elements[0]; | ||
| }; | ||
|
|
||
| // Logic to get list container element | ||
| let targetElement = null; | ||
|
|
||
| for (const element of elements) { | ||
| const deepestEl = findDeepestElement(elements); | ||
|
|
||
| if (deepestEl && element !== deepestEl) { | ||
| if (element.contains(deepestEl) && | ||
| element !== deepestEl.parentElement && | ||
| element.tagName !== 'HTML' && | ||
| element.tagName !== 'BODY') { | ||
| targetElement = element; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| let deepestElement = targetElement || findDeepestElement(elements); | ||
| let deepestElement = findContainerElement(elements); | ||
| if (!deepestElement) return null; | ||
|
Comment on lines
+314
to
337
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Duplicate “container element” heuristic – consider extracting to a helper The identical Suggestion:
This keeps the heuristic single‑sourced and testable. Also applies to: 824-847, 1999-2022 |
||
|
|
||
| const traverseShadowDOM = (element: HTMLElement): HTMLElement => { | ||
|
|
@@ -842,53 +821,29 @@ export const getRect = async (page: Page, coordinates: Coordinates, listSelector | |
| let elements = document.elementsFromPoint(x, y) as HTMLElement[]; | ||
| if (!elements.length) return null; | ||
|
|
||
| const findDeepestElement = (elements: HTMLElement[]): HTMLElement | null => { | ||
| const findContainerElement = (elements: HTMLElement[]): HTMLElement | null => { | ||
| if (!elements.length) return null; | ||
| if (elements.length === 1) return elements[0]; | ||
|
|
||
| let deepestElement = elements[0]; | ||
| let maxDepth = 0; | ||
|
|
||
| for (const element of elements) { | ||
| let depth = 0; | ||
| let current = element; | ||
|
|
||
| while (current) { | ||
| depth++; | ||
| if (current.parentElement) { | ||
| current = current.parentElement; | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
| for (let i = 0; i < elements.length; i++) { | ||
| const element = elements[i]; | ||
| const rect = element.getBoundingClientRect(); | ||
|
|
||
| if (depth > maxDepth) { | ||
| maxDepth = depth; | ||
| deepestElement = element; | ||
| if (rect.width >= 30 && rect.height >= 30) { | ||
| const hasChildrenInList = elements.some((otherElement, j) => | ||
| i !== j && element.contains(otherElement) | ||
| ); | ||
|
|
||
| if (hasChildrenInList) { | ||
| return element; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return deepestElement; | ||
| return elements[0]; | ||
| }; | ||
|
|
||
| // Logic to get list container element | ||
| let targetElement = null; | ||
|
|
||
| for (const element of elements) { | ||
| const deepestEl = findDeepestElement(elements); | ||
|
|
||
| if (deepestEl && element !== deepestEl) { | ||
| if (element.contains(deepestEl) && | ||
| element !== deepestEl.parentElement && | ||
| element.tagName !== 'HTML' && | ||
| element.tagName !== 'BODY') { | ||
| targetElement = element; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| let deepestElement = targetElement || findDeepestElement(elements); | ||
| let deepestElement = findContainerElement(elements); | ||
| if (!deepestElement) return null; | ||
|
|
||
| const traverseShadowDOM = (element: HTMLElement): HTMLElement => { | ||
|
|
@@ -2041,53 +1996,29 @@ export const getNonUniqueSelectors = async (page: Page, coordinates: Coordinates | |
| let elements = document.elementsFromPoint(x, y) as HTMLElement[]; | ||
| if (!elements.length) return null; | ||
|
|
||
| const findDeepestElement = (elements: HTMLElement[]): HTMLElement | null => { | ||
| const findContainerElement = (elements: HTMLElement[]): HTMLElement | null => { | ||
| if (!elements.length) return null; | ||
| if (elements.length === 1) return elements[0]; | ||
|
|
||
| let deepestElement = elements[0]; | ||
| let maxDepth = 0; | ||
|
|
||
| for (const element of elements) { | ||
| let depth = 0; | ||
| let current = element; | ||
|
|
||
| while (current) { | ||
| depth++; | ||
| if (current.parentElement) { | ||
| current = current.parentElement; | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
| for (let i = 0; i < elements.length; i++) { | ||
| const element = elements[i]; | ||
| const rect = element.getBoundingClientRect(); | ||
|
|
||
| if (depth > maxDepth) { | ||
| maxDepth = depth; | ||
| deepestElement = element; | ||
| if (rect.width >= 30 && rect.height >= 30) { | ||
| const hasChildrenInList = elements.some((otherElement, j) => | ||
| i !== j && element.contains(otherElement) | ||
| ); | ||
|
|
||
| if (hasChildrenInList) { | ||
| return element; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return deepestElement; | ||
| return elements[0]; | ||
| }; | ||
|
|
||
| // Logic to get list container element | ||
| let targetElement = null; | ||
|
|
||
| for (const element of elements) { | ||
| const deepestEl = findDeepestElement(elements); | ||
|
|
||
| if (deepestEl && element !== deepestEl) { | ||
| if (element.contains(deepestEl) && | ||
| element !== deepestEl.parentElement && | ||
| element.tagName !== 'HTML' && | ||
| element.tagName !== 'BODY') { | ||
| targetElement = element; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| let deepestElement = targetElement || findDeepestElement(elements); | ||
| let deepestElement = findContainerElement(elements); | ||
| if (!deepestElement) return null; | ||
|
|
||
| const traverseShadowDOM = (element: HTMLElement): HTMLElement => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid adding a new
page.on('console')listener on every callpage.on('console', …)is executed every timegetElementInformationenters thisbranch. After just a few invocations the page will have dozens of identical
listeners, causing:
(You could also register the listener once at module‑initialisation time instead.)
📝 Committable suggestion