diff --git a/CHANGELOG.md b/CHANGELOG.md
index 29d8a7e24..21c29280e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,8 @@ All notable changes to **bUnit** will be documented in this file. The project ad
### Added
- Added `FindByAllByLabel` to `bunit.web.query` package. By [@linkdotnet](https://github.com/linkdotnet).
+- Added generic overloads `Find{TComponent, TElement}` and `FindAll{TComponent, TElement}` to query for specific element types (e.g., `IHtmlInputElement`). By [@linkdotnet](https://github.com/linkdotnet).
+- Added generic overloads `WaitForElement{TComponent, TElement}` and `WaitForElements{TComponent, TElement}` to wait for specific element types. By [@linkdotnet](https://github.com/linkdotnet).
### Fixed
diff --git a/src/bunit/Extensions/RenderedComponentExtensions.cs b/src/bunit/Extensions/RenderedComponentExtensions.cs
index 199ae3316..55a85d27b 100644
--- a/src/bunit/Extensions/RenderedComponentExtensions.cs
+++ b/src/bunit/Extensions/RenderedComponentExtensions.cs
@@ -18,6 +18,21 @@ public static class RenderedComponentExtensions
/// The group of selectors to use.
public static IElement Find(this IRenderedComponent renderedComponent, string cssSelector)
where TComponent : IComponent
+ => Find(renderedComponent, cssSelector);
+
+ ///
+ /// Returns the first element of type from the rendered fragment or component under test,
+ /// using the provided , in a depth-first pre-order traversal
+ /// of the rendered nodes.
+ ///
+ /// The type of the component under test.
+ /// The type of element to find (e.g., IHtmlInputElement).
+ /// The rendered fragment to search.
+ /// The group of selectors to use.
+ /// Thrown if no element matches the .
+ public static TElement Find(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ where TElement : class, IElement
{
ArgumentNullException.ThrowIfNull(renderedComponent);
@@ -26,7 +41,11 @@ public static IElement Find(this IRenderedComponent rend
if (result is null)
throw new ElementNotFoundException(cssSelector);
- return result.WrapUsing(new CssSelectorElementFactory((IRenderedComponent)renderedComponent, cssSelector));
+ if (result is not TElement)
+ throw new ElementNotFoundException(
+ $"The element matching '{cssSelector}' is of type '{result.GetType().Name}', not '{typeof(TElement).Name}'.");
+
+ return (TElement)result.WrapUsing(new CssSelectorElementFactory((IRenderedComponent)renderedComponent, cssSelector));
}
///
@@ -39,10 +58,25 @@ public static IElement Find(this IRenderedComponent rend
/// An , that can be refreshed to execute the search again.
public static IReadOnlyList FindAll(this IRenderedComponent renderedComponent, string cssSelector)
where TComponent : IComponent
+ => FindAll(renderedComponent, cssSelector);
+
+ ///
+ /// Returns a collection of elements of type from the rendered fragment or component under test,
+ /// using the provided , in a depth-first pre-order traversal
+ /// of the rendered nodes. Only elements matching the type are returned.
+ ///
+ /// The type of the component under test.
+ /// The type of elements to find (e.g., IHtmlInputElement).
+ /// The rendered fragment to search.
+ /// The group of selectors to use.
+ /// An containing only elements matching the specified type.
+ public static IReadOnlyList FindAll(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ where TElement : class, IElement
{
ArgumentNullException.ThrowIfNull(renderedComponent);
- return renderedComponent.Nodes.QuerySelectorAll(cssSelector).ToArray();
+ return renderedComponent.Nodes.QuerySelectorAll(cssSelector).OfType().ToArray();
}
///
diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs b/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs
index 9e1e56a14..454778f74 100644
--- a/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs
+++ b/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs
@@ -33,6 +33,37 @@ public static IElement WaitForElement(this IRenderedComponent WaitForElementCore(renderedComponent, cssSelector, timeout: timeout);
+ ///
+ /// Wait until an element of type matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// The type of the component under test.
+ /// The type of element to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for the element.
+ /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details.
+ /// The .
+ public static TElement WaitForElement(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementCore(renderedComponent, cssSelector, timeout: null);
+
+ ///
+ /// Wait until an element of type matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// The type of the component under test.
+ /// The type of element to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for the element.
+ /// The maximum time to wait for the element to appear.
+ /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details.
+ /// The .
+ public static TElement WaitForElement(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementCore(renderedComponent, cssSelector, timeout: timeout);
+
///
/// Wait until at least one element matching the exists in the ,
/// or the timeout is reached (default is one second).
@@ -83,6 +114,70 @@ public static IReadOnlyList WaitForElements(this IRendered
where TComponent : IComponent
=> WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: timeout);
+ ///
+ /// Wait until at least one element of type matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
+
+ ///
+ /// Wait until exactly element(s) of type matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// The exact number of elements to that the should match.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: null);
+
+ ///
+ /// Wait until at least one element of type matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// The maximum time to wait for elements to appear.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: null, timeout: timeout);
+
+ ///
+ /// Wait until exactly element(s) of type matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// The exact number of elements to that the should match.
+ /// The maximum time to wait for elements to appear.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount, TimeSpan timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: timeout);
+
///
/// Wait until an element matching the exists in the ,
/// or the timeout is reached (default is one second).
@@ -107,6 +202,37 @@ public static Task WaitForElementAsync(this IRenderedCompo
where TComponent : IComponent
=> WaitForElementCoreAsync(renderedComponent, cssSelector, timeout: timeout);
+ ///
+ /// Wait until an element of type matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// The type of the component under test.
+ /// The type of element to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for the element.
+ /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details.
+ /// The .
+ public static Task WaitForElementAsync(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementCoreAsync(renderedComponent, cssSelector, timeout: null);
+
+ ///
+ /// Wait until an element of type matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// The type of the component under test.
+ /// The type of element to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for the element.
+ /// The maximum time to wait for the element to appear.
+ /// Thrown if no elements is found matching the within the default timeout. See the inner exception for details.
+ /// The .
+ public static Task WaitForElementAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementCoreAsync(renderedComponent, cssSelector, timeout: timeout);
+
///
/// Wait until exactly element(s) matching the exists in the ,
/// or the timeout is reached (default is one second).
@@ -157,12 +283,80 @@ public static Task> WaitForElementsAsync(thi
/// The .
public static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector)
where TComponent : IComponent
- => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
+ => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
+ ///
+ /// Wait until at least one element of type matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
+
+ ///
+ /// Wait until exactly element(s) of type matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// The exact number of elements to that the should match.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: null);
+
+ ///
+ /// Wait until at least one element of type matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// The maximum time to wait for elements to appear.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: timeout);
+
+ ///
+ /// Wait until exactly element(s) of type matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// The type of the component under test.
+ /// The type of elements to wait for (e.g., IHtmlInputElement).
+ /// The render fragment or component find the matching element in.
+ /// The CSS selector to use to search for elements.
+ /// The exact number of elements to that the should match.
+ /// The maximum time to wait for elements to appear.
+ /// Thrown if no elements is found matching the within the default timeout.
+ /// The .
+ public static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount, TimeSpan timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
+ => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: timeout);
private static IElement WaitForElementCore(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
where TComponent : IComponent
+ => WaitForElementCore(renderedComponent, cssSelector, timeout);
+
+ private static TElement WaitForElementCore(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
{
- using var waiter = new WaitForElementHelper(renderedComponent, cssSelector, timeout);
+ using var waiter = new WaitForElementHelper(renderedComponent, cssSelector, timeout);
try
{
@@ -177,10 +371,15 @@ private static IElement WaitForElementCore(this IRenderedComponent WaitForElementCoreAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
+ private static Task WaitForElementCoreAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
+ where TComponent : IComponent
+ => WaitForElementCoreAsync(renderedComponent, cssSelector, timeout);
+
+ private static async Task WaitForElementCoreAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
where TComponent : IComponent
+ where TElement : class, IElement
{
- using var waiter = new WaitForElementHelper(renderedComponent, cssSelector, timeout);
+ using var waiter = new WaitForElementHelper(renderedComponent, cssSelector, timeout);
return await waiter.WaitTask;
}
@@ -191,8 +390,17 @@ private static IReadOnlyList WaitForElementsCore(
int? matchElementCount,
TimeSpan? timeout)
where TComponent : IComponent
+ => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount, timeout);
+
+ private static IReadOnlyList WaitForElementsCore(
+ this IRenderedComponent renderedComponent,
+ string cssSelector,
+ int? matchElementCount,
+ TimeSpan? timeout)
+ where TComponent : IComponent
+ where TElement : class, IElement
{
- using var waiter = new WaitForElementsHelper(renderedComponent, cssSelector, matchElementCount, timeout);
+ using var waiter = new WaitForElementsHelper(renderedComponent, cssSelector, matchElementCount, timeout);
try
{
@@ -207,14 +415,23 @@ private static IReadOnlyList WaitForElementsCore(
}
}
- private static async Task> WaitForElementsCoreAsync(
+ private static Task> WaitForElementsCoreAsync(
+ this IRenderedComponent renderedComponent,
+ string cssSelector,
+ int? matchElementCount,
+ TimeSpan? timeout)
+ where TComponent : IComponent
+ => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount, timeout);
+
+ private static async Task> WaitForElementsCoreAsync(
this IRenderedComponent renderedComponent,
string cssSelector,
int? matchElementCount,
TimeSpan? timeout)
where TComponent : IComponent
+ where TElement : class, IElement
{
- using var waiter = new WaitForElementsHelper(renderedComponent, cssSelector, matchElementCount, timeout);
+ using var waiter = new WaitForElementsHelper(renderedComponent, cssSelector, matchElementCount, timeout);
return await waiter.WaitTask;
}
diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs
index 316ead9d1..70fd9cf35 100644
--- a/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs
+++ b/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs
@@ -5,8 +5,21 @@ namespace Bunit.Extensions.WaitForHelpers;
///
/// Represents an async wait helper, that will wait for a specified time for an element to become available in the DOM.
///
-internal class WaitForElementHelper : WaitForHelper
+internal class WaitForElementHelper : WaitForElementHelper
where TComponent : IComponent
+{
+ public WaitForElementHelper(IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout = null)
+ : base(renderedComponent, cssSelector, timeout)
+ {
+ }
+}
+
+///
+/// Represents an async wait helper, that will wait for a specified time for an element of type to become available in the DOM.
+///
+internal class WaitForElementHelper : WaitForHelper
+ where TComponent : IComponent
+ where TElement : class, IElement
{
internal const string TimeoutBeforeFoundMessage = "The CSS selector and/or predicate did not result in a matching element before the timeout period passed.";
@@ -19,7 +32,7 @@ internal class WaitForElementHelper : WaitForHelper renderedComponent, string cssSelector, TimeSpan? timeout = null)
: base(renderedComponent, () =>
{
- var element = renderedComponent.Find(cssSelector);
+ var element = renderedComponent.Find(cssSelector);
return (true, element);
}, timeout)
{
diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs
index e53ab8dfb..ec50c9fd4 100644
--- a/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs
+++ b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs
@@ -7,8 +7,21 @@ namespace Bunit.Extensions.WaitForHelpers;
///
/// Represents an async wait helper, that will wait for a specified time for element(s) to become available in the DOM.
///
-internal class WaitForElementsHelper : WaitForHelper, TComponent>
+internal class WaitForElementsHelper : WaitForElementsHelper
where TComponent : IComponent
+{
+ public WaitForElementsHelper(IRenderedComponent renderedComponent, string cssSelector, int? matchElementCount, TimeSpan? timeout = null)
+ : base(renderedComponent, cssSelector, matchElementCount, timeout)
+ {
+ }
+}
+
+///
+/// Represents an async wait helper, that will wait for a specified time for element(s) of type to become available in the DOM.
+///
+internal class WaitForElementsHelper : WaitForHelper, TComponent>
+ where TComponent : IComponent
+ where TElement : class, IElement
{
internal const string TimeoutBeforeFoundMessage = "The CSS selector did not result in any matching element(s) before the timeout period passed.";
internal static readonly CompositeFormat TimeoutBeforeFoundWithCountMessage = CompositeFormat.Parse("The CSS selector did not result in exactly {0} matching element(s) before the timeout period passed.");
@@ -25,7 +38,7 @@ internal class WaitForElementsHelper : WaitForHelper renderedComponent, string cssSelector, int? matchElementCount, TimeSpan? timeout = null)
: base(renderedComponent, () =>
{
- var elements = renderedComponent.FindAll(cssSelector);
+ var elements = renderedComponent.FindAll(cssSelector);
var checkPassed = matchElementCount is null
? elements.Count > 0
diff --git a/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs
index e7f4b844b..295fdf844 100644
--- a/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs
+++ b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs
@@ -1,4 +1,5 @@
using System.Globalization;
+using AngleSharp.Html.Dom;
namespace Bunit.Extensions.WaitForHelpers;
@@ -97,4 +98,55 @@ public void Test025()
elms.ShouldBeEmpty();
}
+
+ [Fact(DisplayName = "WaitForElement waits until element of specified type matching cssSelector appears")]
+ [Trait("Category", "sync")]
+ public void Test026()
+ {
+ var expectedMarkup = "";
+ var cut = Render(ps => ps.AddChildContent(expectedMarkup));
+
+ var elm = cut.WaitForElement("#myInput");
+
+ elm.ShouldNotBeNull();
+ elm.Type.ShouldBe("text");
+ }
+
+ [Fact(DisplayName = "WaitForElement throws exception when element type does not match")]
+ [Trait("Category", "sync")]
+ public void Test027()
+ {
+ var cut = Render(ps => ps.AddChildContent(""));
+
+ var expected = Should.Throw(() =>
+ cut.WaitForElement("#myDiv", WaitForTestTimeout));
+
+ expected.InnerException.ShouldBeOfType();
+ }
+
+ [Fact(DisplayName = "WaitForElements waits until elements of specified type matching cssSelector appear")]
+ [Trait("Category", "sync")]
+ public void Test028()
+ {
+ var expectedMarkup = "";
+ var cut = Render(ps => ps.AddChildContent(expectedMarkup));
+
+ var elms = cut.WaitForElements("main input");
+
+ elms.Count.ShouldBe(2);
+ elms[0].ShouldBeAssignableTo();
+ elms[1].ShouldBeAssignableTo();
+ }
+
+ [Fact(DisplayName = "WaitForElements with count waits until exactly N elements of specified type appear")]
+ [Trait("Category", "sync")]
+ public void Test029()
+ {
+ var expectedMarkup = "";
+ var cut = Render(ps => ps.AddChildContent(expectedMarkup));
+
+ var elms = cut.WaitForElements("main input", matchElementCount: 3);
+
+ elms.Count.ShouldBe(3);
+ }
}
diff --git a/tests/bunit.tests/Rendering/RenderedComponentTest.cs b/tests/bunit.tests/Rendering/RenderedComponentTest.cs
index 2c1866495..bdf04d193 100644
--- a/tests/bunit.tests/Rendering/RenderedComponentTest.cs
+++ b/tests/bunit.tests/Rendering/RenderedComponentTest.cs
@@ -1,4 +1,5 @@
using AngleSharp.Dom;
+using AngleSharp.Html.Dom;
using Bunit.Rendering;
namespace Bunit;
@@ -255,7 +256,47 @@ public void Test025()
cut.Instance.Invoked.ShouldBeTrue();
}
-
+
+ [Fact(DisplayName = "Find returns element of specified type when it matches")]
+ public void Test026()
+ {
+ var cut = Render(x => x.AddChildContent(""));
+
+ var result = cut.Find("#myInput");
+
+ result.ShouldNotBeNull();
+ result.Type.ShouldBe("text");
+ }
+
+ [Fact(DisplayName = "Find throws ElementNotFoundException when no element matches selector")]
+ public void Test027()
+ {
+ var cut = Render(x => x.AddChildContent(""));
+
+ Should.Throw(() => cut.Find("#nonexistent"));
+ }
+
+ [Fact(DisplayName = "FindAll returns only elements of specified type")]
+ public void Test028()
+ {
+ var cut = Render(x => x.AddChildContent(""));
+
+ var results = cut.FindAll("*");
+
+ results.Count.ShouldBe(2);
+ results.ShouldAllBe(e => e is IHtmlInputElement);
+ }
+
+ [Fact(DisplayName = "FindAll returns empty list when no elements match the type")]
+ public void Test029()
+ {
+ var cut = Render(x => x.AddChildContent(""));
+
+ var results = cut.FindAll("*");
+
+ results.ShouldBeEmpty();
+ }
+
private class BaseComponent : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)