2121using OpenQA . Selenium . Environment ;
2222using System . Collections . Generic ;
2323using System . Collections . ObjectModel ;
24+ using System . Linq ;
2425
2526namespace OpenQA . Selenium
2627{
@@ -29,21 +30,42 @@ namespace OpenQA.Selenium
2930 public class RelativeLocatorTest : DriverTestFixture
3031 {
3132 [ Test ]
32- public void ShouldBeAbleToFindElementsAboveAnother ( )
33+ public void ShouldBeAbleToFindElementsAboveAnotherWithTagName ( )
3334 {
3435 driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
3536
3637 IWebElement lowest = driver . FindElement ( By . Id ( "below" ) ) ;
3738
3839 ReadOnlyCollection < IWebElement > elements = driver . FindElements ( RelativeBy . WithLocator ( By . TagName ( "p" ) ) . Above ( lowest ) ) ;
39- List < string > elementIds = new List < string > ( ) ;
40- foreach ( IWebElement element in elements )
41- {
42- string id = element . GetAttribute ( "id" ) ;
43- elementIds . Add ( id ) ;
44- }
4540
46- Assert . That ( elementIds , Is . EquivalentTo ( new List < string > ( ) { "above" , "mid" } ) ) ;
41+ var values = elements . Select ( element => element . GetDomAttribute ( "id" ) ) ;
42+ Assert . That ( values , Is . EquivalentTo ( new List < string > ( ) { "above" , "mid" } ) ) ;
43+ }
44+
45+ [ Test ]
46+ public void ShouldBeAbleToFindElementsAboveAnotherWithXpath ( )
47+ {
48+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
49+
50+ IWebElement lowest = driver . FindElement ( By . Id ( "seventh" ) ) ;
51+
52+ var elements = driver . FindElements ( RelativeBy . WithLocator ( By . XPath ( "//td[1]" ) ) . Above ( lowest ) ) ;
53+
54+ var values = elements . Select ( element => element . GetDomAttribute ( "id" ) ) ;
55+ Assert . That ( values , Is . EquivalentTo ( new List < string > { "fourth" , "first" } ) ) ;
56+ }
57+
58+ [ Test ]
59+ public void ShouldBeAbleToFindElementsAboveAnotherWithCssSelector ( )
60+ {
61+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
62+
63+ IWebElement lowest = driver . FindElement ( By . Id ( "below" ) ) ;
64+
65+ var elements = driver . FindElements ( RelativeBy . WithLocator ( By . CssSelector ( "p" ) ) . Above ( lowest ) ) ;
66+
67+ var values = elements . Select ( element => element . GetDomAttribute ( "id" ) ) ;
68+ Assert . That ( values , Is . EquivalentTo ( new List < string > { "mid" , "above" } ) ) ;
4769 }
4870
4971 [ Test ]
@@ -53,14 +75,170 @@ public void ShouldBeAbleToCombineFilters()
5375
5476 ReadOnlyCollection < IWebElement > seen = driver . FindElements ( RelativeBy . WithLocator ( By . TagName ( "td" ) ) . Above ( By . Id ( "center" ) ) . RightOf ( By . Id ( "second" ) ) ) ;
5577
56- List < string > elementIds = new List < string > ( ) ;
57- foreach ( IWebElement element in seen )
78+ var elementIds = seen . Select ( element => element . GetDomAttribute ( "id" ) ) ;
79+ Assert . That ( elementIds , Is . EquivalentTo ( new List < string > ( ) { "third" } ) ) ;
80+ }
81+
82+
83+ [ Test ]
84+ public void ShouldBeAbleToCombineFiltersWithXpath ( )
85+ {
86+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
87+
88+ ReadOnlyCollection < IWebElement > seen = driver . FindElements ( RelativeBy . WithLocator ( By . XPath ( "//td[1]" ) ) . Below ( By . Id ( "second" ) ) . Above ( By . Id ( "seventh" ) ) ) ;
89+
90+ var values = seen . Select ( element => element . GetDomAttribute ( "id" ) ) ;
91+ Assert . That ( values , Is . EquivalentTo ( new List < string > { "fourth" } ) ) ;
92+ }
93+
94+ [ Test ]
95+ public void ShouldBeAbleToCombineFiltersWithCssSelector ( )
96+ {
97+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
98+
99+ ReadOnlyCollection < IWebElement > seen = driver . FindElements (
100+ RelativeBy . WithLocator ( By . CssSelector ( "td" ) ) . Above ( By . Id ( "center" ) ) . RightOf ( By . Id ( "second" ) ) ) ;
101+
102+ var values = seen . Select ( element => element . GetDomAttribute ( "id" ) ) ;
103+ Assert . That ( values , Is . EquivalentTo ( new List < string > { "third" } ) ) ;
104+ }
105+
106+ [ Test ]
107+ public void ExerciseNearLocatorWithTagName ( )
108+ {
109+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
110+
111+ ReadOnlyCollection < IWebElement > seen = driver . FindElements ( RelativeBy . WithLocator ( By . TagName ( "td" ) ) . Near ( By . Id ( "center" ) ) ) ;
112+
113+ // Elements are sorted by proximity and then DOM insertion order.
114+ // Proximity is determined using distance from center points, so
115+ // we expect the order to be:
116+ // 1. Directly above (short vertical distance, first in DOM)
117+ // 2. Directly below (short vertical distance, later in DOM)
118+ // 3. Directly left (slight longer distance horizontally, first in DOM)
119+ // 4. Directly right (slight longer distance horizontally, later in DOM)
120+ // 5-8. Diagonally close (pythagoras sorting, with top row first
121+ // because of DOM insertion order)
122+ 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" } ) ) ;
124+ }
125+
126+ [ Test ]
127+ public void ExerciseNearLocatorWithXpath ( )
128+ {
129+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
130+
131+ ReadOnlyCollection < IWebElement > seen = driver . FindElements ( RelativeBy . WithLocator ( By . XPath ( "//td" ) ) . Near ( By . Id ( "center" ) ) ) ;
132+
133+ // Elements are sorted by proximity and then DOM insertion order.
134+ // Proximity is determined using distance from center points, so
135+ // we expect the order to be:
136+ // 1. Directly above (short vertical distance, first in DOM)
137+ // 2. Directly below (short vertical distance, later in DOM)
138+ // 3. Directly left (slight longer distance horizontally, first in DOM)
139+ // 4. Directly right (slight longer distance horizontally, later in DOM)
140+ // 5-8. Diagonally close (pythagoras sorting, with top row first
141+ // because of DOM insertion order)
142+ 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" } ) ) ;
144+ }
145+
146+ [ Test ]
147+ public void ExerciseNearLocatorWithCssSelector ( )
148+ {
149+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
150+
151+ ReadOnlyCollection < IWebElement > seen = driver . FindElements ( RelativeBy . WithLocator ( By . CssSelector ( "td" ) ) . Near ( By . Id ( "center" ) ) ) ;
152+
153+ // Elements are sorted by proximity and then DOM insertion order.
154+ // Proximity is determined using distance from center points, so
155+ // we expect the order to be:
156+ // 1. Directly above (short vertical distance, first in DOM)
157+ // 2. Directly below (short vertical distance, later in DOM)
158+ // 3. Directly left (slight longer distance horizontally, first in DOM)
159+ // 4. Directly right (slight longer distance horizontally, later in DOM)
160+ // 5-8. Diagonally close (pythagoras sorting, with top row first
161+ // because of DOM insertion order)
162+ 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" } ) ) ;
164+ }
165+
166+ [ Test ]
167+ public void EnsureNoRepeatedElements ( )
168+ {
169+ driver . Url = EnvironmentManager . Instance . UrlBuilder . CreateInlinePage ( new InlinePage ( )
170+ . WithTitle ( "Repeated Elements" )
171+ . WithStyles (
172+ """
173+ .c {
174+ position: absolute;
175+ border: 1px solid black;
176+ height: 50px;
177+ width: 50px;
178+ }
179+ """
180+ )
181+ . WithBody (
182+ """
183+ <span style="position: relative;">
184+ <div id= "a" class="c" style="left:25;top:0;">El-A</div>
185+ <div id= "b" class="c" style="left:78;top:30;">El-B</div>
186+ <div id= "c" class="c" style="left:131;top:60;">El-C</div>
187+ <div id= "d" class="c" style="left:0;top:53;">El-D</div>
188+ <div id= "e" class="c" style="left:53;top:83;">El-E</div>
189+ <div id= "f" class="c" style="left:106;top:113;">El-F</div>
190+ </span>
191+ """
192+ ) ) ;
193+
194+ IWebElement @base = driver . FindElement ( By . Id ( "e" ) ) ;
195+ ReadOnlyCollection < IWebElement > cells = driver . FindElements ( RelativeBy . WithLocator ( By . TagName ( "div" ) ) . Above ( @base ) ) ;
196+
197+ IWebElement a = driver . FindElement ( By . Id ( "a" ) ) ;
198+ IWebElement b = driver . FindElement ( By . Id ( "b" ) ) ;
199+
200+ var values = cells . Select ( element => element . GetDomAttribute ( "id" ) ) ;
201+ Assert . That ( values , Is . EqualTo ( new List < string > { b . GetDomAttribute ( "id" ) , a . GetDomAttribute ( "id" ) } ) ) ;
202+ }
203+
204+ [ Test ]
205+ public void NearLocatorShouldFindNearElements ( )
206+ {
207+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
208+
209+ var rect1 = driver . FindElement ( By . Id ( "rect1" ) ) ;
210+
211+ var rect2 = driver . FindElement ( RelativeBy . WithLocator ( By . Id ( "rect2" ) ) . Near ( rect1 ) ) ;
212+
213+ Assert . That ( rect2 . GetDomAttribute ( "id" ) , Is . EqualTo ( "rect2" ) ) ;
214+ }
215+
216+ [ Test ]
217+ public void NearLocatorShouldNotFindFarElements ( )
218+ {
219+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
220+
221+ var rect3 = driver . FindElement ( By . Id ( "rect3" ) ) ;
222+
223+ Assert . That ( ( ) =>
58224 {
59- string id = element . GetAttribute ( "id" ) ;
60- elementIds . Add ( id ) ;
61- }
225+ var rect2 = driver . FindElement ( RelativeBy . WithLocator ( By . Id ( "rect4" ) ) . Near ( rect3 ) ) ;
62226
63- Assert . That ( elementIds , Is . EquivalentTo ( new List < string > ( ) { "third" } ) ) ;
227+ } , 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" ) ) ;
228+ }
229+
230+ //------------------------------------------------------------------
231+ // Tests below here are not included in the Java test suite
232+ //------------------------------------------------------------------
233+
234+ [ Test ]
235+ public void ShouldReturnEmptyListWhenNoElementsFound ( )
236+ {
237+ driver . Url = ( EnvironmentManager . Instance . UrlBuilder . WhereIs ( "relative_locators.html" ) ) ;
238+
239+ var elements = driver . FindElements ( RelativeBy . WithLocator ( By . TagName ( "does-not-exist" ) ) ) ;
240+
241+ Assert . That ( elements , Is . Empty ) ;
64242 }
65243 }
66244}
0 commit comments