Skip to content

[🐛 Bug]: "Near" relative locator fails to find elements under certain conditions #11272

@alpatron

Description

@alpatron

What happened?

The "near" relative locator fails to locate elements in certain cases, like when a narrower object is directly above a wider object (see provided screenshot).
obrazek

In this case, trying to locate " 'Rectangle 1' near 'Rectangle 2' " results in a NoSuchElementException exception even though the rectangles certainly look like they are within 50 px of each other.

I actually located the source of the issue:

// Ascii art time!
//
// +---+
// | 1 |
// +---+ +---+
// | 2 |
// +---+
//
// As you can see, the right hand side of 1 is "left of" the left-most
// edge of 2. The top edge of 2 is at the same level as the bottom
// edge of 1. This means that 1 is "above" 2, and 2 is "below" one.
// Distance from left edge to right edge
var leftDistance = Math.abs(rect1.left - (rect2.left + rect2.width));
// Distance from right edge to left edge
var rightDistance = Math.abs((rect1.left + rect1.width) - rect2.left);
// Distance from top to bottom
var topDistance = Math.abs(rect1.top - (rect2.top + rect2.height));
// Distance from bottom to top
var bottomDistance = Math.abs((rect1.top + rect1.height) - rect2.top);
var horizontallyClose = leftDistance <= distance || rightDistance <= distance;
var verticallyClose = topDistance <= distance || bottomDistance <= distance;
if (horizontallyClose && verticallyClose) {
return true;
}
// Distance from centre points
var x1 = rect1.left + (rect1.width / 2);
var y1 = rect1.top + (rect1.height / 2);
var x2 = rect2.left + (rect2.width / 2);
var y2 = rect2.top + (rect2.height / 2);
var xDistance = Math.abs(x1 - x2);
var yDistance = Math.abs(y1 - y2);
var dist = Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
return dist <= distance;

The algorithm to determine the proximity of object boundaries seems to perform some naive calculations, whereas what probably is desired is to calculate the shortest distance between the two rectangles' boundaries (or centres if they are overlapping).

So the code probably ought to look something like the example in this StackOverflow answer (https://stackoverflow.com/a/26178015).

I wrote that this issue is present in Selenium 4.6.0 for Python, but since the issue seems to stem from some JavaScript atoms, the issue is probably present in all versions of Selenium, but I did not check, since I only use Selenium for Python.

How can we reproduce the issue?

https://github.com/alpatron/SeleniumRelativeLocatorBug

Relevant log output

DevTools listening on ws://127.0.0.1:12320/devtools/browser/9ef7f89b-4fcb-40f3-9789-dbff1edade6b
Traceback (most recent call last):
  File "C:\Users\Vikto\Desktop\SeleniumTests Big Boy\SeleniumRelativeLocatorBug\bug.py", line 8, in <module>
    driver.find_element(
  File "C:\Users\Vikto\Desktop\SeleniumTests Big Boy\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 848, in find_element
    raise NoSuchElementException(f"Cannot locate relative element with: {by.root}")
selenium.common.exceptions.NoSuchElementException: Message: Cannot locate relative element with: {'id': 'rect1'}

Operating System

Windows 10 21H1

Selenium version

Python 4.6.0 (but should be present in all versions; see "What happened" section)

What are the browser(s) and version(s) where you see this issue?

Chrome 107

What are the browser driver(s) and version(s) where you see this issue?

ChromeDriver 107.0.5304.62

Are you using Selenium Grid?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-defectSomething is not working as intendedJ-awaiting answerQuestion asked of user; a reply moves it to triage again

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions