diff --git a/dotnet/src/webdriver/ShadowRoot.cs b/dotnet/src/webdriver/ShadowRoot.cs
index a616a7e14ebbc..76139f657db0f 100644
--- a/dotnet/src/webdriver/ShadowRoot.cs
+++ b/dotnet/src/webdriver/ShadowRoot.cs
@@ -30,7 +30,7 @@ namespace OpenQA.Selenium
///
/// Provides a representation of an element's shadow root.
///
- public class ShadowRoot : ISearchContext, IWrapsDriver, IWebDriverObjectReference
+ public class ShadowRoot : ISearchContext, IWrapsDriver, IWebDriverObjectReference, IFindsElement
{
///
/// The property name that represents an element shadow root in the wire protocol.
@@ -93,10 +93,21 @@ public IWebElement FindElement(By by)
throw new ArgumentNullException(nameof(by), "by cannot be null");
}
+ return by.FindElement(this);
+ }
+
+ ///
+ /// Finds a child element matching the given mechanism and value.
+ ///
+ /// The mechanism by which to find the element.
+ /// The value to use to search for the element.
+ /// The first matching the given criteria.
+ public virtual IWebElement FindElement(string mechanism, string value)
+ {
Dictionary parameters = new Dictionary();
parameters.Add("id", this.shadowRootId);
- parameters.Add("using", by.Mechanism);
- parameters.Add("value", by.Criteria);
+ parameters.Add("using", mechanism);
+ parameters.Add("value", value);
Response commandResponse = this.driver.InternalExecute(DriverCommand.FindShadowChildElement, parameters);
return this.driver.GetElementFromResponse(commandResponse)!;
@@ -117,10 +128,21 @@ public ReadOnlyCollection FindElements(By by)
throw new ArgumentNullException(nameof(by), "by cannot be null");
}
+ return by.FindElements(this);
+ }
+
+ ///
+ /// Finds all child elements matching the given mechanism and value.
+ ///
+ /// The mechanism by which to find the elements.
+ /// The value to use to search for the elements.
+ /// A collection of all of the IWebElements matching the given criteria.
+ public virtual ReadOnlyCollection FindElements(string mechanism, string value)
+ {
Dictionary parameters = new Dictionary();
parameters.Add("id", this.shadowRootId);
- parameters.Add("using", by.Mechanism);
- parameters.Add("value", by.Criteria);
+ parameters.Add("using", mechanism);
+ parameters.Add("value", value);
Response commandResponse = this.driver.InternalExecute(DriverCommand.FindShadowChildElements, parameters);
return this.driver.GetElementsFromResponse(commandResponse);
diff --git a/dotnet/test/common/ShadowRootHandlingTest.cs b/dotnet/test/common/ShadowRootHandlingTest.cs
index 7fa25654dd10f..561118db89ca8 100644
--- a/dotnet/test/common/ShadowRootHandlingTest.cs
+++ b/dotnet/test/common/ShadowRootHandlingTest.cs
@@ -18,6 +18,7 @@
//
using NUnit.Framework;
+using System.Collections.ObjectModel;
namespace OpenQA.Selenium
{
@@ -42,8 +43,23 @@ public void ShouldFindElementUnderShadowRoot()
driver.Url = shadowRootPage;
IWebElement element = driver.FindElement(By.CssSelector("custom-checkbox-element"));
ISearchContext shadowRoot = element.GetShadowRoot();
+
IWebElement elementInShadow = shadowRoot.FindElement(By.CssSelector("input"));
Assert.That(elementInShadow.GetAttribute("type"), Is.EqualTo("checkbox"), "Did not find element in shadow root");
+
+ ReadOnlyCollection elementsInShadow = shadowRoot.FindElements(By.CssSelector("input"));
+ Assert.That(elementsInShadow, Has.One.Items, "Did not find element in shadow root");
+ Assert.That(elementsInShadow[0].GetAttribute("type"), Is.EqualTo("checkbox"), "Did not find element in shadow root");
+ }
+
+ [Test]
+ [IgnoreBrowser(Browser.Firefox, "Firefox does not support finding Shadow DOM elements")]
+ public void ShouldUseByMethodsToFindElementsUnderShadowRoot()
+ {
+ driver.Url = shadowRootPage;
+ IWebElement element = driver.FindElement(By.CssSelector("custom-checkbox-element"));
+ ISearchContext shadowRoot = element.GetShadowRoot();
+ Assert.That(shadowRoot.FindElements(By.Id("")), Is.Empty, "Searching for elements by empty ID should return empty");
}
[Test]