Bug: `get_element_coordinates` returns `None` for a visible element whose first content quad is degenerate · Issue #6153 · browser-use/browser-use · GitHub
Skip to content

Bug: get_element_coordinates returns None for a visible element whose first content quad is degenerate #6153

Open
wannT-1/browser-use
#3

Description

@yifanxiong272

Browser Use Version

0.13.11 (c75e8476). The method is unchanged on current main (0.13.13, aa093a84).

Bug Description, Steps to Reproduce, Screenshots

BrowserSession.get_element_coordinates documents that it "tries DOM.getContentQuads first, then falls back to DOM.getBoxModel, and finally uses JavaScript getBoundingClientRect", and that it returns "None if element not found/no bounds" (browser_use/browser/session.py:2830-2838).

DOM.getContentQuads can return a non-empty list whose first quad has zero width or height while the element itself has bounds. One example is an inline element that starts with a line break:

<div style="width:60px">aaaa <span id="t"><br>bbbbb</span></div>

For the span, Chromium returns

  • DOM.getContentQuads: [[28.40625, 0, 28.40625, 0, 28.40625, 17, 28.40625, 17], [0, 18, 40, 18, 40, 35, 0, 35]] (first quad zero width, second quad 40x17)
  • DOM.getBoxModel content: [0, 0, 40, 0, 40, 35, 0, 35] (40x35)
  • getBoundingClientRect(): positive width and height

get_element_coordinates returns None for it:

  1. The quad list is non-empty, so the getBoxModel fallback (if not quads, session.py:2857) and the getBoundingClientRect fallback (session.py:2883) are both skipped.
  2. Only quads[0] is used (session.py:2921). Its width is 0, so the width > 0 and height > 0 check (session.py:2935) fails and the method returns None.

The click path then logs "Could not get element geometry from any method, falling back to JavaScript click" (browser/watchdogs/default_action_watchdog.py:778-803), although every method could have given geometry.

Steps:

  1. uv pip install browser-use==0.13.11 (or main).
  2. Run the test below with pytest. It feeds get_element_coordinates the CDP replies listed above, which were recorded from Chromium (headless shell, Chromium 139) for that HTML.

Possible fix: skip degenerate quads (use the first quad with positive area), and fall back to getBoxModel / getBoundingClientRect when none has positive area, instead of deciding the fallback by if not quads.

Failing Python Code

"""get_element_coordinates returns None for an element that has bounds.

The CDP replies below are the ones real Chromium returns for
<div style="width:60px">aaaa <span id="t"><br>bbbbb</span></div>: the span's first
content quad has zero width (the line break), its second quad and its box model do not.
"""
import asyncio
from types import SimpleNamespace

from browser_use.browser.profile import BrowserProfile
from browser_use.browser.session import BrowserSession

CONTENT_QUADS = {"quads": [[28.40625, 0, 28.40625, 0, 28.40625, 17, 28.40625, 17],
                           [0, 18, 40, 18, 40, 35, 0, 35]]}
BOX_MODEL = {"model": {"content": [0, 0, 40, 0, 40, 35, 0, 35]}}


class DOM:
    async def getContentQuads(self, params, session_id=None):
        return CONTENT_QUADS

    async def getBoxModel(self, params, session_id=None):
        return BOX_MODEL


def cdp_session():
    return SimpleNamespace(session_id="s1", cdp_client=SimpleNamespace(send=SimpleNamespace(DOM=DOM())))


def test_element_with_bounds_gets_coordinates():
    session = BrowserSession(browser_profile=BrowserProfile(headless=True))
    rect = asyncio.run(session.get_element_coordinates(backend_node_id=1, cdp_session=cdp_session()))
    # Documented: falls back to DOM.getBoxModel; returns None only if the element is not found or has no bounds.
    assert rect is not None, "element has a 40x35 box but get_element_coordinates returned None"
    assert (rect.x, rect.y, rect.width, rect.height) == (0, 0, 40, 35)

LLM Model

Not applicable (no LLM involved).

Operating System & Browser Versions

Ubuntu 22.04.5 LTS, x86_64; Chromium 139 headless shell (Playwright chromium_headless_shell-1181) for the recorded replies; Python 3.13.9.

Full DEBUG Log Output

E       AssertionError: element has a 40x35 box but get_element_coordinates returned None
E       assert None is not None
FAILED test_coordinates.py::test_element_with_bounds_gets_coordinates

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions