Skip to content

Commit 960ff05

Browse files
AdamPDottypujagani
andauthored
[java][js][py] Add straight relative-by locators (#14482)
Co-authored-by: Puja Jagani <puja.jagani93@gmail.com>
1 parent 835c8a0 commit 960ff05

File tree

13 files changed

+964
-306
lines changed

13 files changed

+964
-306
lines changed

common/src/web/relative_locators.html

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
<html>
1+
<html lang="en">
32
<head>
43
<title>Relative Locators</title>
54
<style>
@@ -10,57 +9,101 @@
109
td {
1110
border: solid;
1211
}
13-
.small-rectangle {
12+
#center {
13+
width: 100px;
14+
}
15+
#rectangles {
16+
position: relative;
17+
}
18+
#rectangles div {
19+
position: absolute;
20+
border: 1px solid black;
21+
height: 50px;
22+
width: 50px;
23+
}
24+
#a {
25+
left: 25px;
26+
top: 0;
27+
}
28+
#b {
29+
left: 78px;
30+
top: 30px;
31+
}
32+
#c {
33+
left: 131px;
34+
top: 60px;
35+
}
36+
#d {
37+
left: 0;
38+
top: 53px;
39+
}
40+
#e {
41+
left: 53px;
42+
top: 83px;
43+
}
44+
#f {
45+
left: 106px;
46+
top: 113px;
47+
}
48+
#proximity .small {
1449
border: 1px solid black;
1550
width: 100px;
1651
height: 50px;
1752
margin: 5px 25px;
1853
}
19-
.big-rectangle {
54+
#proximity .big {
2055
border: 1px solid black;
2156
width: 150px;
22-
height: 400px;
57+
height: 400px;
58+
}
59+
#rect3 {
60+
margin: 60px 25px;
2361
}
2462
</style>
2563
</head>
2664
<body>
2765
<h1>Relative Locator Tests</h1>
28-
<p id="above">This text is above.
29-
<p id="mid">This is a paragraph of text in the middle.
30-
<p id="below">This text is below.
31-
66+
<section id="paragraphs">
67+
<p id="above">This text is above.</p>
68+
<p id="mid">This is a paragraph of text in the middle.</p>
69+
<p id="below">This text is below.</p>
70+
</section>
3271

3372
<table>
3473
<tr>
35-
<td id="first">1</td>
36-
<td id="second" style="width: 100px">2</td>
37-
<td id="third">3</td>
74+
<td id="topLeft">1</td>
75+
<td id="top">2</td>
76+
<td id="topRight">3</td>
3877
</tr>
3978
<tr>
40-
<td id="fourth">4</td>
79+
<td id="left">4</td>
4180
<td id="center">5</td>
42-
<td id="sixth">6</td>
81+
<td id="right">6</td>
4382
</tr>
4483
<tr>
45-
<td id="seventh">7</td>
46-
<td id="eighth">8</td>
47-
<td id="ninth">9</td>
84+
<td id="bottomLeft">7</td>
85+
<td id="bottom">8</td>
86+
<td id="bottomRight">9</td>
4887
</tr>
4988
</table>
5089

51-
<div class="small-rectangle" id="rect1">
52-
Rectangle 1
53-
</div>
54-
<div class="big-rectangle" id="rect2">
55-
Rectangle 2, which is near Rectangle 1
56-
</div>
90+
<section id="rectangles">
91+
<div id="a">El-A</div>
92+
<div id="b">El-B</div>
93+
<div id="c">El-C</div>
94+
<div id="d">El-D</div>
95+
<div id="e">El-E</div>
96+
<div id="f">El-F</div>
97+
</section>
5798

58-
<div class="small-rectangle" style="margin:60px 25px" id="rect3">
59-
Rectangle 3
60-
</div>
61-
<div class="big-rectangle" id="rect4">
62-
Rectangle 4, which is not near Rectangle 2 because it is more than 50 px away
63-
</div>
99+
<section id="proximity">
100+
<div class="small" id="rect1">Rectangle 1</div>
101+
<div class="big" id="rect2">Rectangle 2, which is near Rectangle 1</div>
102+
<div class="small" id="rect3">Rectangle 3</div>
103+
<div class="big" id="rect4">
104+
Rectangle 4, which is not near Rectangle 2 because it is more than 50 px away
105+
</div>
106+
</section>
64107

65108
</body>
66109
</html>

dotnet/test/common/RelativeLocatorTest.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ public void ShouldBeAbleToFindElementsAboveAnotherWithXpath()
4747
{
4848
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
4949

50-
IWebElement lowest = driver.FindElement(By.Id("seventh"));
50+
IWebElement lowest = driver.FindElement(By.Id("bottomLeft"));
5151

5252
var elements = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Above(lowest));
5353

5454
var values = elements.Select(element => element.GetDomAttribute("id"));
55-
Assert.That(values, Is.EquivalentTo(new List<string> { "fourth", "first" }));
55+
Assert.That(values, Is.EquivalentTo(new List<string> { "left", "topLeft" }));
5656
}
5757

5858
[Test]
@@ -73,10 +73,10 @@ public void ShouldBeAbleToCombineFilters()
7373
{
7474
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
7575

76-
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.TagName("td")).Above(By.Id("center")).RightOf(By.Id("second")));
76+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.TagName("td")).Above(By.Id("center")).RightOf(By.Id("top")));
7777

7878
var elementIds = seen.Select(element => element.GetDomAttribute("id"));
79-
Assert.That(elementIds, Is.EquivalentTo(new List<string>() { "third" }));
79+
Assert.That(elementIds, Is.EquivalentTo(new List<string>() { "topRight" }));
8080
}
8181

8282

@@ -85,10 +85,10 @@ public void ShouldBeAbleToCombineFiltersWithXpath()
8585
{
8686
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
8787

88-
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Below(By.Id("second")).Above(By.Id("seventh")));
88+
ReadOnlyCollection<IWebElement> seen = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Below(By.Id("top")).Above(By.Id("bottomLeft")));
8989

9090
var values = seen.Select(element => element.GetDomAttribute("id"));
91-
Assert.That(values, Is.EquivalentTo(new List<string> { "fourth" }));
91+
Assert.That(values, Is.EquivalentTo(new List<string> { "left" }));
9292
}
9393

9494
[Test]
@@ -97,10 +97,10 @@ public void ShouldBeAbleToCombineFiltersWithCssSelector()
9797
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
9898

9999
ReadOnlyCollection<IWebElement> seen = driver.FindElements(
100-
RelativeBy.WithLocator(By.CssSelector("td")).Above(By.Id("center")).RightOf(By.Id("second")));
100+
RelativeBy.WithLocator(By.CssSelector("td")).Above(By.Id("center")).RightOf(By.Id("top")));
101101

102102
var values = seen.Select(element => element.GetDomAttribute("id"));
103-
Assert.That(values, Is.EquivalentTo(new List<string> { "third" }));
103+
Assert.That(values, Is.EquivalentTo(new List<string> { "topRight" }));
104104
}
105105

106106
[Test]
@@ -120,7 +120,7 @@ public void ExerciseNearLocatorWithTagName()
120120
// 5-8. Diagonally close (pythagoras sorting, with top row first
121121
// because of DOM insertion order)
122122
var values = seen.Select(element => element.GetDomAttribute("id"));
123-
Assert.That(values, Is.EquivalentTo(new List<string> { "second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth" }));
123+
Assert.That(values, Is.EquivalentTo(new List<string> { "top", "bottom", "left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight" }));
124124
}
125125

126126
[Test]
@@ -140,7 +140,7 @@ public void ExerciseNearLocatorWithXpath()
140140
// 5-8. Diagonally close (pythagoras sorting, with top row first
141141
// because of DOM insertion order)
142142
var values = seen.Select(element => element.GetDomAttribute("id"));
143-
Assert.That(values, Is.EquivalentTo(new List<string> { "second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth" }));
143+
Assert.That(values, Is.EquivalentTo(new List<string> { "top", "bottom", "left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight" }));
144144
}
145145

146146
[Test]
@@ -160,7 +160,7 @@ public void ExerciseNearLocatorWithCssSelector()
160160
// 5-8. Diagonally close (pythagoras sorting, with top row first
161161
// because of DOM insertion order)
162162
var values = seen.Select(element => element.GetDomAttribute("id"));
163-
Assert.That(values, Is.EquivalentTo(new List<string> { "second", "eighth", "fourth", "sixth", "first", "third", "seventh", "ninth" }));
163+
Assert.That(values, Is.EquivalentTo(new List<string> { "top", "bottom", "left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight" }));
164164
}
165165

166166
[Test]
@@ -218,11 +218,11 @@ public void NearLocatorShouldNotFindFarElements()
218218
{
219219
driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html"));
220220

221-
var rect3 = driver.FindElement(By.Id("rect3"));
221+
var rect = driver.FindElement(By.Id("rect1"));
222222

223223
Assert.That(() =>
224224
{
225-
var rect2 = driver.FindElement(RelativeBy.WithLocator(By.Id("rect4")).Near(rect3));
225+
var rect2 = driver.FindElement(RelativeBy.WithLocator(By.Id("rect4")).Near(rect));
226226

227227
}, Throws.TypeOf<NoSuchElementException>().With.Message.EqualTo("Unable to find element; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception"));
228228
}

java/src/org/openqa/selenium/support/locators/RelativeLocator.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,50 @@ public RelativeBy toRightOf(By locator) {
147147
return simpleDirection("right", locator);
148148
}
149149

150+
public RelativeBy straightAbove(WebElement element) {
151+
Require.nonNull("Element to search straight above of", element);
152+
return simpleDirection("straightAbove", element);
153+
}
154+
155+
public RelativeBy straightAbove(By locator) {
156+
Require.nonNull("Locator", locator);
157+
assertLocatorCanBeSerialized(locator);
158+
return simpleDirection("straightAbove", locator);
159+
}
160+
161+
public RelativeBy straightBelow(WebElement element) {
162+
Require.nonNull("Element to search straight below of", element);
163+
return simpleDirection("straightBelow", element);
164+
}
165+
166+
public RelativeBy straightBelow(By locator) {
167+
Require.nonNull("Locator", locator);
168+
assertLocatorCanBeSerialized(locator);
169+
return simpleDirection("straightBelow", locator);
170+
}
171+
172+
public RelativeBy straightLeftOf(WebElement element) {
173+
Require.nonNull("Element to search straight to the left of", element);
174+
return simpleDirection("straightLeft", element);
175+
}
176+
177+
public RelativeBy straightLeftOf(By locator) {
178+
Require.nonNull("Locator", locator);
179+
assertLocatorCanBeSerialized(locator);
180+
return simpleDirection("straightLeft", locator);
181+
}
182+
183+
public RelativeBy straightRightOf(WebElement element) {
184+
Require.nonNull("Element to search straight to the right of", element);
185+
return simpleDirection("straightRight", element);
186+
}
187+
188+
public RelativeBy straightRightOf(By locator) {
189+
Require.nonNull("Locator", locator);
190+
assertLocatorCanBeSerialized(locator);
191+
return simpleDirection("straightRight", locator);
192+
}
193+
150194
public RelativeBy near(WebElement element) {
151195
Require.nonNull("Element to search near", element);
152196
return near(element, CLOSE_IN_PIXELS);

0 commit comments

Comments
 (0)