Skip to content

Commit

Permalink
Rework near relative locator to be easier to understand
Browse files Browse the repository at this point in the history
  • Loading branch information
shs96c committed Dec 14, 2020
1 parent 8996ec2 commit 2cf77cc
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 24 deletions.
Expand Up @@ -89,6 +89,7 @@ public class RelativeLocator {
throw new UncheckedIOException(e);
}
}
private static final int CLOSE_IN_PIXELS = 100;

/**
* Start of a relative locator, finding elements by tag name.
Expand Down Expand Up @@ -169,7 +170,7 @@ public RelativeBy toRightOf(By locator) {

public RelativeBy near(WebElement element) {
Require.nonNull("Element to search near", element);
return near(element, 50);
return near(element, CLOSE_IN_PIXELS);
}

public RelativeBy near(WebElement element, int atMostDistanceInPixels) {
Expand All @@ -181,7 +182,7 @@ public RelativeBy near(WebElement element, int atMostDistanceInPixels) {

public RelativeBy near(By locator) {
Require.nonNull("Locator", locator);
return near((Object) locator, 50);
return near((Object) locator, CLOSE_IN_PIXELS);
}

public RelativeBy near(By locator, int atMostDistanceInPixels) {
Expand All @@ -199,7 +200,7 @@ private RelativeBy near(Object locator, int atMostDistanceInPixels) {
root,
amend(ImmutableMap.of(
"kind", "near",
"args", ImmutableList.of(asAtomLocatorParameter(locator), "distance", atMostDistanceInPixels))));
"args", ImmutableList.of(asAtomLocatorParameter(locator), atMostDistanceInPixels))));
}

@Override
Expand Down
Expand Up @@ -6,6 +6,10 @@ java_selenium_test_suite(
size = "medium",
srcs = glob(["*Test.java"]),
browsers = ["chrome"],
javacopts = [
"--release",
"11",
],
deps = [
"//java/client/src/org/openqa/selenium:core",
"//java/client/src/org/openqa/selenium/remote",
Expand Down
Expand Up @@ -22,7 +22,6 @@
import org.openqa.selenium.WebElement;
import org.openqa.selenium.testing.JUnit4TestBase;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -41,7 +40,7 @@ public void shouldBeAbleToFindElementsAboveAnother() {
List<WebElement> elements = driver.findElements(withTagName("p").above(lowest));
List<String> ids = elements.stream().map(e -> e.getAttribute("id")).collect(Collectors.toList());

assertThat(ids).isEqualTo(Arrays.asList("mid", "above"));
assertThat(ids).isEqualTo(List.of("mid", "above"));
}

@Test
Expand All @@ -54,4 +53,22 @@ public void shouldBeAbleToCombineFilters() {
assertThat(ids).isEqualTo(singletonList("third"));
}

@Test
public void exerciseNearLocator() {
driver.get(appServer.whereIs("relative_locators.html"));

List<WebElement> seen = driver.findElements(withTagName("td").near(By.id("center")));

// Elements are sorted by proximity and then DOM insertion order.
// Proximity is determined using distance from center points, so
// we expect the order to be:
// 1. Directly above (short vertical distance, first in DOM)
// 2. Directly below (short vertical distance, later in DOM)
// 3. Directly left (slight longer distance horizontally, first in DOM)
// 4. Directly right (slight longer distance horizontally, later in DOM)
// 5-8. Diagonally close (pythagorus sorting, with top row first
// because of DOM insertion order)
List<String> ids = seen.stream().map(e -> e.getAttribute("id")).collect(Collectors.toList());
assertThat(ids).isEqualTo(List.of("second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth"));
}
}
48 changes: 29 additions & 19 deletions javascript/atoms/locators/relative.js
Expand Up @@ -145,11 +145,11 @@ bot.locators.relative.near_ = function (selector, opt_distance) {
distance = opt_distance;
} else if (goog.isNumber(selector['distance'])) {
distance = /** @type {number} */ (selector['distance']);
delete selector['distance'];
// delete selector['distance'];
}

if (!distance) {
distance = 50;
distance = 100;
}

/**
Expand Down Expand Up @@ -179,29 +179,39 @@ bot.locators.relative.near_ = function (selector, opt_distance) {
// we would be comparing the right hand side of 2 to the left hand side
// of 1. Similar logic happens for top and bottom.

var rhs1 = rect1.left + rect1.width;
var rhs2 = rect2.left + rect2.width;
var bottom1 = rect1.top - rect1.height;
var bottom2 = rect2.top - rect2.height;
// Distance from left edge to right edge
var leftDistance = Math.abs(rect1.left - (rect2.left + rect2.width));

/** @type {function():boolean} */
var verticalProximity = function () {
return Math.abs(bottom1 - rect2.top) <= distance ||
Math.abs(bottom2 - rect1.top) <= distance;
};
// Distance from right edge to left edge
var rightDistance = Math.abs((rect1.left + rect1.width) - rect2.left);

// Is 1 to the right of 2?
if (Math.abs(rhs1 - rect2.left) <= distance) {
return verticalProximity();
}
// 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;

// Is 1 to the left of 2?
if (Math.abs(rhs2 - rect1.left) <= distance) {
return verticalProximity();
if (horizontallyClose && verticallyClose) {
return true;
}

return false;
// 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;
};

return func;
};

Expand Down

0 comments on commit 2cf77cc

Please sign in to comment.