// // Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // using NUnit.Framework; using OpenQA.Selenium.Environment; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace OpenQA.Selenium; [TestFixture] [IgnoreBrowser(Browser.IE, "IE does not like this JS")] public class RelativeLocatorTest : DriverTestFixture { [Test] public void ShouldBeAbleToFindElementsAboveAnotherWithTagName() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); IWebElement lowest = driver.FindElement(By.Id("below")); ReadOnlyCollection elements = driver.FindElements(RelativeBy.WithLocator(By.TagName("p")).Above(lowest)); var values = elements.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List() { "above", "mid" })); } [Test] public void ShouldBeAbleToFindElementsAboveAnotherWithXpath() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); IWebElement lowest = driver.FindElement(By.Id("bottomLeft")); var elements = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Above(lowest)); var values = elements.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "left", "topLeft" })); } [Test] public void ShouldBeAbleToFindElementsAboveAnotherWithCssSelector() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); IWebElement lowest = driver.FindElement(By.Id("below")); var elements = driver.FindElements(RelativeBy.WithLocator(By.CssSelector("p")).Above(lowest)); var values = elements.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "mid", "above" })); } [Test] public void ShouldBeAbleToCombineFilters() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); ReadOnlyCollection seen = driver.FindElements(RelativeBy.WithLocator(By.TagName("td")).Above(By.Id("center")).RightOf(By.Id("top"))); var elementIds = seen.Select(element => element.GetDomAttribute("id")); Assert.That(elementIds, Is.EquivalentTo(new List() { "topRight" })); } [Test] public void ShouldBeAbleToCombineFiltersWithXpath() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); ReadOnlyCollection seen = driver.FindElements(RelativeBy.WithLocator(By.XPath("//td[1]")).Below(By.Id("top")).Above(By.Id("bottomLeft"))); var values = seen.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "left" })); } [Test] public void ShouldBeAbleToCombineFiltersWithCssSelector() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); ReadOnlyCollection seen = driver.FindElements( RelativeBy.WithLocator(By.CssSelector("td")).Above(By.Id("center")).RightOf(By.Id("top"))); var values = seen.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "topRight" })); } [Test] public void ExerciseNearLocatorWithTagName() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); ReadOnlyCollection seen = driver.FindElements(RelativeBy.WithLocator(By.TagName("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 (pythagoras sorting, with top row first // because of DOM insertion order) var values = seen.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "top", "bottom", "left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight" })); } [Test] public void ExerciseNearLocatorWithXpath() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); ReadOnlyCollection seen = driver.FindElements(RelativeBy.WithLocator(By.XPath("//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 (pythagoras sorting, with top row first // because of DOM insertion order) var values = seen.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "top", "bottom", "left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight" })); } [Test] public void ExerciseNearLocatorWithCssSelector() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); ReadOnlyCollection seen = driver.FindElements(RelativeBy.WithLocator(By.CssSelector("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 (pythagoras sorting, with top row first // because of DOM insertion order) var values = seen.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EquivalentTo(new List { "top", "bottom", "left", "right", "topLeft", "topRight", "bottomLeft", "bottomRight" })); } [Test] public void EnsureNoRepeatedElements() { driver.Url = EnvironmentManager.Instance.UrlBuilder.CreateInlinePage(new InlinePage() .WithTitle("Repeated Elements") .WithStyles( """ .c { position: absolute; border: 1px solid black; height: 50px; width: 50px; } """ ) .WithBody( """
El-A
El-B
El-C
El-D
El-E
El-F
""" )); IWebElement @base = driver.FindElement(By.Id("e")); ReadOnlyCollection cells = driver.FindElements(RelativeBy.WithLocator(By.TagName("div")).Above(@base)); IWebElement a = driver.FindElement(By.Id("a")); IWebElement b = driver.FindElement(By.Id("b")); var values = cells.Select(element => element.GetDomAttribute("id")); Assert.That(values, Is.EqualTo(new List { b.GetDomAttribute("id"), a.GetDomAttribute("id") })); } [Test] public void NearLocatorShouldFindNearElements() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); var rect1 = driver.FindElement(By.Id("rect1")); var rect2 = driver.FindElement(RelativeBy.WithLocator(By.Id("rect2")).Near(rect1)); Assert.That(rect2.GetDomAttribute("id"), Is.EqualTo("rect2")); } [Test] public void NearLocatorShouldNotFindFarElements() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); var rect = driver.FindElement(By.Id("rect1")); Assert.That(() => { var rect2 = driver.FindElement(RelativeBy.WithLocator(By.Id("rect4")).Near(rect)); }, Throws.TypeOf().With.Message.EqualTo("Unable to find element; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#nosuchelementexception")); } //------------------------------------------------------------------ // Tests below here are not included in the Java test suite //------------------------------------------------------------------ [Test] public void ShouldReturnEmptyListWhenNoElementsFound() { driver.Url = (EnvironmentManager.Instance.UrlBuilder.WhereIs("relative_locators.html")); var elements = driver.FindElements(RelativeBy.WithLocator(By.TagName("does-not-exist"))); Assert.That(elements, Is.Empty); } }