diff --git a/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs
index d5dc40768..22ab2474c 100644
--- a/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs
+++ b/src/bunit/EventDispatchExtensions/TriggerEventDispatchExtensions.cs
@@ -67,7 +67,7 @@ public static Task TriggerEventAsync(this IElement element, string eventName, Ev
// TriggerEventsAsync will traverse the DOM tree to find
// all event handlers that needs to be triggered. This is done
- // in the renderes synchronization context to avoid a race condition
+ // in the renderer synchronization context to avoid a race condition
// between the DOM tree being updated and traversed.
var result = renderer.Dispatcher.InvokeAsync(
() => TriggerEventsAsync(renderer, element, eventName, eventArgs));
diff --git a/src/bunit/Extensions/IRefreshableElementCollection.cs b/src/bunit/Extensions/IRefreshableElementCollection.cs
deleted file mode 100644
index b98c0e093..000000000
--- a/src/bunit/Extensions/IRefreshableElementCollection.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using AngleSharp.Dom;
-
-namespace Bunit;
-
-///
-/// Represents a collection, which queries and finds its
-/// elements in an , based on a CSS selector.
-/// The collection can be refreshed either manually or automatically.
-///
-/// The type of in the collection.
-public interface IRefreshableElementCollection : IReadOnlyList
- where T : IElement
-{
- ///
- /// Gets or sets a value indicating whether the collection automatically refreshes when the
- /// changes.
- ///
- bool EnableAutoRefresh { get; set; }
-
- ///
- /// Trigger a refresh of the elements in the collection, by querying the rendered fragments DOM tree.
- ///
- void Refresh();
-}
diff --git a/src/bunit/Extensions/Internal/RefreshableElementCollection.cs b/src/bunit/Extensions/Internal/RefreshableElementCollection.cs
deleted file mode 100644
index f6041fe2a..000000000
--- a/src/bunit/Extensions/Internal/RefreshableElementCollection.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System.Collections;
-using System.Diagnostics;
-using AngleSharp.Dom;
-
-namespace Bunit;
-
-[DebuggerDisplay("Selector={cssSelector}, AutoRefresh={enableAutoRefresh}")]
-internal sealed class RefreshableElementCollection : IRefreshableElementCollection
-{
- private readonly IRenderedComponent renderedComponent;
- private readonly string cssSelector;
- private IHtmlCollection elements;
- private bool enableAutoRefresh;
-
- public bool EnableAutoRefresh
- {
- get => enableAutoRefresh;
- set
- {
- if (ShouldEnable(value))
- {
- renderedComponent.OnMarkupUpdated += RefreshInternal;
- }
-
- if (ShouldDisable(value))
- {
- renderedComponent.OnMarkupUpdated -= RefreshInternal;
- }
-
- enableAutoRefresh = value;
- }
- }
-
- private bool ShouldDisable(bool value) => !value && enableAutoRefresh;
-
- private bool ShouldEnable(bool value) => value && !enableAutoRefresh;
-
- internal RefreshableElementCollection(IRenderedComponent renderedComponent, string cssSelector)
- {
- this.renderedComponent = renderedComponent;
- this.cssSelector = cssSelector;
- elements = renderedComponent.Nodes.QuerySelectorAll(cssSelector);
- }
-
- public void Refresh() => RefreshInternal(this, EventArgs.Empty);
-
- public IElement this[int index] => elements[index];
-
- public int Count => elements.Length;
-
- public IEnumerator GetEnumerator() => elements.GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- private void RefreshInternal(object? sender, EventArgs args)
- {
- elements = renderedComponent.Nodes.QuerySelectorAll(cssSelector);
- }
-}
diff --git a/src/bunit/Extensions/RenderedComponentExtensions.cs b/src/bunit/Extensions/RenderedComponentExtensions.cs
index dfbefd584..585ff9d29 100644
--- a/src/bunit/Extensions/RenderedComponentExtensions.cs
+++ b/src/bunit/Extensions/RenderedComponentExtensions.cs
@@ -21,12 +21,7 @@ public static IElement Find(this IRenderedComponent rend
{
ArgumentNullException.ThrowIfNull(renderedComponent);
- var result = renderedComponent.Nodes.QuerySelector(cssSelector);
-
- if (result is null)
- throw new ElementNotFoundException(cssSelector);
-
- return result.WrapUsing(new CssSelectorElementFactory((IRenderedComponent)renderedComponent, cssSelector));
+ return renderedComponent.FindAsync(cssSelector, timeout: TimeSpan.Zero).GetAwaiter().GetResult();
}
///
@@ -36,13 +31,13 @@ public static IElement Find(this IRenderedComponent rend
///
/// The rendered fragment to search.
/// The group of selectors to use.
- /// If true, the returned will automatically refresh its s whenever the changes.
- /// An , that can be refreshed to execute the search again.
- public static IRefreshableElementCollection FindAll(this IRenderedComponent renderedComponent, string cssSelector, bool enableAutoRefresh = false)
+ /// Obsolete: This parameter is no longer used and will be removed in a future version.
+ public static IReadOnlyList FindAll(this IRenderedComponent renderedComponent, string cssSelector, bool enableAutoRefresh = false)
where TComponent : IComponent
{
ArgumentNullException.ThrowIfNull(renderedComponent);
- return new RefreshableElementCollection((IRenderedComponent)renderedComponent, cssSelector) { EnableAutoRefresh = enableAutoRefresh };
+
+ return renderedComponent.FindAllAsync(cssSelector, TimeSpan.Zero).GetAwaiter().GetResult();
}
///
@@ -87,4 +82,15 @@ public static IReadOnlyList> FindComponents<
/// True if the contains the ; otherwise false.
public static bool HasComponent(this IRenderedComponent renderedComponent)
where TChildComponent : IComponent => FindComponents(renderedComponent).Count > 0;
+
+ ///
+ /// Finds all elements from the rendered fragment or component under test,
+ ///
+ internal static IReadOnlyList FindAllInternal(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ {
+ ArgumentNullException.ThrowIfNull(renderedComponent);
+
+ return renderedComponent.FindAllAsync(cssSelector).GetAwaiter().GetResult();
+ }
}
diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedComponentFindAsyncExtensions.cs b/src/bunit/Extensions/WaitForHelpers/RenderedComponentFindAsyncExtensions.cs
new file mode 100644
index 000000000..2bc332a56
--- /dev/null
+++ b/src/bunit/Extensions/WaitForHelpers/RenderedComponentFindAsyncExtensions.cs
@@ -0,0 +1,103 @@
+using AngleSharp.Dom;
+using Bunit.Extensions.WaitForHelpers;
+
+namespace Bunit;
+
+///
+/// Helper methods that deal with asynchronous retrieval of elements from a rendered component.
+///
+public static class RenderedComponentFindAsyncExtensions
+{
+ ///
+ /// Wait until an element matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// 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 FindAsync(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent => FindCoreAsync(renderedComponent, cssSelector, timeout: null);
+
+ ///
+ /// Wait until an element matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// 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 FindAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ where TComponent : IComponent
+ => FindCoreAsync(renderedComponent, cssSelector, timeout: timeout);
+
+ ///
+ /// Wait until exactly element(s) matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// 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.
+ public static Task> FindAllAsync(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount)
+ where TComponent : IComponent
+ => FindAllCoreAsync(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: null);
+
+ ///
+ /// Wait until at least one element matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// 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.
+ public static Task> FindAllAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ where TComponent : IComponent
+ => FindAllCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: timeout);
+
+ ///
+ /// Wait until exactly element(s) matching the exists in the ,
+ /// or the is reached.
+ ///
+ /// 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.
+ public static Task> FindAllAsync(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount, TimeSpan timeout)
+ where TComponent : IComponent
+ => FindAllCoreAsync(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: timeout);
+
+ ///
+ /// Wait until at least one element matching the exists in the ,
+ /// or the timeout is reached (default is one second).
+ ///
+ /// 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.
+ public static Task> FindAllAsync(this IRenderedComponent renderedComponent, string cssSelector)
+ where TComponent : IComponent
+ => FindAllCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
+
+ private static async Task FindCoreAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
+ where TComponent : IComponent
+ {
+ using var waiter = new WaitForElementHelper(renderedComponent, cssSelector, timeout);
+
+ return await waiter.WaitTask;
+ }
+
+
+ private static async Task> FindAllCoreAsync(
+ this IRenderedComponent renderedComponent,
+ string cssSelector,
+ int? matchElementCount,
+ TimeSpan? timeout)
+ where TComponent : IComponent
+ {
+ using var waiter = new WaitForElementsHelper(renderedComponent, cssSelector, matchElementCount, timeout);
+
+ return (await waiter.WaitTask).ToArray();
+ }
+}
diff --git a/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs b/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs
index 912dece39..4a278dd0a 100644
--- a/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs
+++ b/src/bunit/Extensions/WaitForHelpers/RenderedComponentWaitForHelperExtensions.WaitForElement.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics;
using System.Runtime.ExceptionServices;
using AngleSharp.Dom;
using Bunit.Extensions.WaitForHelpers;
@@ -40,8 +41,7 @@ public static IElement WaitForElement(this IRenderedComponentThe 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 IRefreshableElementCollection WaitForElements(this IRenderedComponent renderedComponent, string cssSelector)
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector)
where TComponent : IComponent => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
///
@@ -52,8 +52,7 @@ public static IRefreshableElementCollection WaitForElementsThe 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 IRefreshableElementCollection WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount)
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount)
where TComponent : IComponent => WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: null);
///
@@ -64,8 +63,7 @@ public static IRefreshableElementCollection WaitForElementsThe 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 IRefreshableElementCollection WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
where TComponent : IComponent
=> WaitForElementsCore(renderedComponent, cssSelector, matchElementCount: null, timeout: timeout);
@@ -78,87 +76,10 @@ public static IRefreshableElementCollection WaitForElementsThe 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 IRefreshableElementCollection WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount, TimeSpan timeout)
+ public static IReadOnlyList WaitForElements(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount, TimeSpan timeout)
where TComponent : IComponent
=> 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).
- ///
- /// 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 .
- internal static Task WaitForElementAsync(this IRenderedComponent renderedComponent, string cssSelector)
- where TComponent : IComponent => WaitForElementCoreAsync(renderedComponent, cssSelector, timeout: null);
-
- ///
- /// Wait until an element matching the exists in the ,
- /// or the is reached.
- ///
- /// 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 .
- internal static Task WaitForElementAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
- where TComponent : IComponent
- => WaitForElementCoreAsync(renderedComponent, cssSelector, timeout: timeout);
-
- ///
- /// Wait until exactly element(s) matching the exists in the ,
- /// or the timeout is reached (default is one second).
- ///
- /// 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 .
- internal static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount)
- where TComponent : IComponent
- => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: null);
-
- ///
- /// Wait until at least one element matching the exists in the ,
- /// or the is reached.
- ///
- /// 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 .
- internal static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan timeout)
- where TComponent : IComponent
- => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: timeout);
-
- ///
- /// Wait until exactly element(s) matching the exists in the ,
- /// or the is reached.
- ///
- /// 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 .
- internal static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector, int matchElementCount, TimeSpan timeout)
- where TComponent : IComponent
- => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: matchElementCount, timeout: timeout);
-
- ///
- /// Wait until at least one element matching the exists in the ,
- /// or the timeout is reached (default is one second).
- ///
- /// 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 .
- internal static Task> WaitForElementsAsync(this IRenderedComponent renderedComponent, string cssSelector)
- where TComponent : IComponent
- => WaitForElementsCoreAsync(renderedComponent, cssSelector, matchElementCount: null, timeout: null);
-
private static IElement WaitForElementCore(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
where TComponent : IComponent
{
@@ -172,20 +93,10 @@ private static IElement WaitForElementCore(this IRenderedComponent WaitForElementCoreAsync(this IRenderedComponent renderedComponent, string cssSelector, TimeSpan? timeout)
- where TComponent : IComponent
- {
- using var waiter = new WaitForElementHelper(renderedComponent, cssSelector, timeout);
-
- return await waiter.WaitTask;
- }
-
- private static IRefreshableElementCollection WaitForElementsCore(
+ private static IElement[] WaitForElementsCore(
this IRenderedComponent renderedComponent,
string cssSelector,
int? matchElementCount,
@@ -196,26 +107,13 @@ private static IRefreshableElementCollection WaitForElementsCore> WaitForElementsCoreAsync(
- this IRenderedComponent renderedComponent,
- string cssSelector,
- int? matchElementCount,
- TimeSpan? timeout)
- where TComponent : IComponent
- {
- 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..8830fc42b 100644
--- a/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs
+++ b/src/bunit/Extensions/WaitForHelpers/WaitForElementHelper.cs
@@ -1,4 +1,5 @@
using AngleSharp.Dom;
+using Bunit.Web.AngleSharp;
namespace Bunit.Extensions.WaitForHelpers;
@@ -19,9 +20,19 @@ internal class WaitForElementHelper : WaitForHelper renderedComponent, string cssSelector, TimeSpan? timeout = null)
: base(renderedComponent, () =>
{
- var element = renderedComponent.Find(cssSelector);
+ var element = FindElement(renderedComponent, cssSelector);
return (true, element);
}, timeout)
{
}
+
+ private static IElement FindElement(IRenderedComponent renderedComponent, string cssSelector)
+ {
+ var result = renderedComponent.Nodes.QuerySelector(cssSelector);
+
+ if (result is null)
+ throw new ElementNotFoundException(cssSelector);
+
+ return result.WrapUsing(new CssSelectorElementFactory((IRenderedComponent)renderedComponent, cssSelector));
+ }
}
diff --git a/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs
index 53f477193..29da6b442 100644
--- a/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs
+++ b/src/bunit/Extensions/WaitForHelpers/WaitForElementsHelper.cs
@@ -1,13 +1,14 @@
using System.Globalization;
using System.Text;
using AngleSharp.Dom;
+using Bunit.Web.AngleSharp;
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 : WaitForHelper, TComponent>
where TComponent : IComponent
{
internal const string TimeoutBeforeFoundMessage = "The CSS selector did not result in any matching element(s) before the timeout period passed.";
@@ -25,15 +26,18 @@ internal class WaitForElementsHelper : WaitForHelper renderedComponent, string cssSelector, int? matchElementCount, TimeSpan? timeout = null)
: base(renderedComponent, () =>
{
- var elements = renderedComponent.FindAll(cssSelector);
+ var elements = FindAllElements(renderedComponent, cssSelector);
var checkPassed = matchElementCount is null
- ? elements.Count > 0
- : elements.Count == matchElementCount;
+ ? elements.Length > 0
+ : elements.Length == matchElementCount;
return (checkPassed, elements);
}, timeout)
{
this.matchElementCount = matchElementCount;
}
+
+ private static IHtmlCollection FindAllElements(IRenderedComponent renderedComponent, string cssSelector)
+ => renderedComponent.Nodes.QuerySelectorAll(cssSelector);
}
diff --git a/tests/bunit.tests/BlazorE2E/ComponentRenderingTest.cs b/tests/bunit.tests/BlazorE2E/ComponentRenderingTest.cs
index f7ec92b68..16d2f04e2 100644
--- a/tests/bunit.tests/BlazorE2E/ComponentRenderingTest.cs
+++ b/tests/bunit.tests/BlazorE2E/ComponentRenderingTest.cs
@@ -101,27 +101,29 @@ public void CanTriggerAsyncEventHandlers_Sync()
}
[Fact]
- public void CanTriggerKeyPressEvents()
+ public async Task CanTriggerKeyPressEvents()
{
// List is initially empty
var cut = Render();
var inputElement = cut.Find("input");
- var liElements = cut.FindAll("li", enableAutoRefresh: true);
+ var liElements = await cut.FindAllAsync("li", 0);
liElements.ShouldBeEmpty();
// Typing adds element
inputElement.KeyPress("a");
+ liElements = await cut.FindAllAsync("li");
liElements.ShouldAllBe(li => Assert.Equal("a", li.TextContent));
// Typing again adds another element
inputElement.KeyPress("b");
+ liElements = await cut.FindAllAsync("li");
liElements.ShouldAllBe(
li => Assert.Equal("a", li.TextContent),
li => Assert.Equal("b", li.TextContent));
}
[Fact]
- public void CanAddAndRemoveEventHandlersDynamically()
+ public async Task CanAddAndRemoveEventHandlersDynamically()
{
var cut = Render();
var countDisplayElement = cut.Find("p");
@@ -135,7 +137,7 @@ public void CanAddAndRemoveEventHandlersDynamically()
// We can remove an event handler
toggleClickHandlerCheckbox.Change(false);
- Assert.Empty(cut.FindAll("#listening-message"));
+ Assert.Empty(await cut.FindAllAsync("#listening-message", 0));
incrementButton.Click();
Assert.Equal("Current count: 1", countDisplayElement.TextContent);
@@ -229,13 +231,13 @@ public void ChildComponentsRerenderWhenPropertiesChanged()
}
[Fact]
- public void CanAddAndRemoveChildComponentsDynamically()
+ public async Task CanAddAndRemoveChildComponentsDynamically()
{
// Initially there are zero child components
var cut = Render();
var addButton = cut.Find(".addChild");
var removeButton = cut.Find(".removeChild");
- Assert.Empty(cut.FindAll("p"));
+ Assert.Empty(await cut.FindAllAsync("p", 0));
// Click to add/remove some child components
addButton.Click();
@@ -279,13 +281,13 @@ public void ChildComponentsNotifiedWhenPropertiesChanged()
}
[Fact]
- public void CanRenderFragmentsWhilePreservingSurroundingElements()
+ public async Task CanRenderFragmentsWhilePreservingSurroundingElements()
{
// Initially, the region isn't shown
var cut = Render();
var originalButton = cut.Find("button");
- var fragmentElements = cut.FindAll("p[name=fragment-element]", enableAutoRefresh: true);
+ var fragmentElements = await cut.FindAllAsync("p[name=fragment-element]", 0);
Assert.Empty(fragmentElements);
// The JS-side DOM builder handles regions correctly, placing elements
@@ -294,10 +296,12 @@ public void CanRenderFragmentsWhilePreservingSurroundingElements()
// When we click the button, the region is shown
originalButton.Click();
+ fragmentElements = await cut.FindAllAsync("p[name=fragment-element]");
fragmentElements.Single().ShouldNotBeNull();
// The button itself was preserved, so we can click it again and see the effect
originalButton.Click();
+ fragmentElements = await cut.FindAllAsync("p[name=fragment-element]", 0);
Assert.Empty(fragmentElements);
}
@@ -429,7 +433,7 @@ public void CanCaptureReferencesToDynamicallyAddedElements()
}
[Fact]
- public void CanCaptureReferencesToDynamicallyAddedComponents()
+ public async Task CanCaptureReferencesToDynamicallyAddedComponents()
{
var cut = Render();
var incrementButton = cut.Find("#child-component button");
@@ -447,7 +451,7 @@ public void CanCaptureReferencesToDynamicallyAddedComponents()
// Remove and re-add a new instance of the child, checking the text was reset
toggleChildCheckbox.Change(false);
- Assert.Empty(cut.FindAll("#child-component button"));
+ Assert.Empty(await cut.FindAllAsync("#child-component button", 0));
toggleChildCheckbox.Change(true);
Assert.Equal("Current count: 0", currentCountText.TextContent);
@@ -664,22 +668,10 @@ public async Task CanHandleRemovedParentObjects()
cut.Find("button").Click();
- await cut.WaitForStateAsync(() => !cut.FindAll("div").Any());
- cut.FindAll("div").Count.ShouldBe(0);
+ var allElements = await cut.FindAllAsync("div", 0);
+ allElements.Count.ShouldBe(0);
}
-
- [Fact]
- [Trait("Category", "sync")]
- public void CanHandleRemovedParentObjects_Sync()
- {
- var cut = Render();
-
- cut.Find("button").Click();
-
- cut.WaitForState(() => !cut.FindAll("div").Any());
- cut.FindAll("div").Count.ShouldBe(0);
- }
-
+
[Fact]
[Trait("Category", "async")]
public async Task CanHandleRemovedParentObjectsAsync()
@@ -688,8 +680,8 @@ public async Task CanHandleRemovedParentObjectsAsync()
await cut.Find("button").ClickAsync(new MouseEventArgs());
- await cut.WaitForStateAsync(() => !cut.FindAll("div").Any());
- cut.FindAll("div").Count.ShouldBe(0);
+ var elements = await cut.FindAllAsync("div", 0);
+ elements.Count.ShouldBe(0);
}
[Theory]
@@ -712,8 +704,8 @@ public async Task CanHandleRemovedParentObjectsAsync_Sync()
await cut.Find("button").ClickAsync(new MouseEventArgs());
- cut.WaitForState(() => !cut.FindAll("div").Any());
- cut.FindAll("div").Count.ShouldBe(0);
+ var allElements = await cut.FindAllAsync("div", 0);
+ allElements.Count.ShouldBe(0);
}
[Fact]
diff --git a/tests/bunit.tests/Extensions/RefreshableQueryCollectionTest.cs b/tests/bunit.tests/Extensions/RefreshableQueryCollectionTest.cs
deleted file mode 100644
index 91036fb81..000000000
--- a/tests/bunit.tests/Extensions/RefreshableQueryCollectionTest.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-namespace Bunit;
-
-public class RefreshableQueryCollectionTest : BunitContext
-{
- [Fact(DisplayName = "When the query returns no elements, the collection is empty")]
- public void Test001()
- {
- var cut = Render();
-
- var sut = new RefreshableElementCollection(cut, ".foo");
-
- sut.ShouldBeEmpty();
- }
-
- [Fact(DisplayName = "When the query returns elements, the collection contains those elements")]
- public void Test002()
- {
- var cut = Render();
-
- var sut = new RefreshableElementCollection(cut, "h1");
-
- sut.Count.ShouldBe(1);
- sut[0].TagName.ShouldBe("H1");
- }
-
- [Fact(DisplayName = "When Refresh is called, the query is run again and new elements are made available")]
- public void Test003()
- {
- var cut = Render();
- var sut = new RefreshableElementCollection(cut, "li");
- sut.Count.ShouldBe(0);
-
- cut.Find("button").Click();
-
- sut.Refresh();
- sut.Count.ShouldBe(1);
- }
-
- [Fact(DisplayName = "Enabling auto refresh automatically refreshes query when the rendered fragment renders and has changes")]
- public void Test004()
- {
- var cut = Render();
- var sut = new RefreshableElementCollection(cut, "li") { EnableAutoRefresh = true };
- sut.Count.ShouldBe(0);
-
- cut.Find("button").Click();
-
- sut.Count.ShouldBe(1);
- }
-
- [Fact(DisplayName = "Disabling auto refresh turns off automatic refreshing queries on when rendered fragment changes")]
- public void Test005()
- {
- var cut = Render();
- var sut = new RefreshableElementCollection(cut, "li") { EnableAutoRefresh = true };
-
- sut.EnableAutoRefresh = false;
-
- cut.Find("button").Click();
-
- sut.Count.ShouldBe(0);
- }
-}
diff --git a/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensions.Test.cs b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensions.Test.cs
deleted file mode 100644
index 15167b052..000000000
--- a/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensions.Test.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using System.Globalization;
-
-namespace Bunit.Extensions.WaitForHelpers;
-
-public class RenderedComponentWaitForElementsHelperExtensions : BunitContext
-{
- private readonly static TimeSpan WaitForTestTimeout = TimeSpan.FromMilliseconds(5);
-
- public RenderedComponentWaitForElementsHelperExtensions(ITestOutputHelper testOutput)
- {
- BunitContext.DefaultWaitTimeout = TimeSpan.FromSeconds(30);
- Services.AddXunitLogger(testOutput);
- }
-
- [Fact(DisplayName = "WaitForElement waits until cssSelector returns at a element")]
- [Trait("Category", "async")]
- public async Task Test001()
- {
- var expectedMarkup = "child content
";
- var cut = Render(ps => ps.AddChildContent(expectedMarkup));
-
- var elm = await cut.WaitForElementAsync("main > p");
-
- elm.MarkupMatches(expectedMarkup);
- }
-
- [Fact(DisplayName = "WaitForElement throws exception after timeout when cssSelector does not result in matching element")]
- [Trait("Category", "async")]
- public async Task Test002()
- {
- var cut = Render();
-
- var expected = await Should.ThrowAsync(async () =>
- await cut.WaitForElementAsync("#notHereElm", WaitForTestTimeout));
-
- expected.Message.ShouldStartWith(WaitForElementHelper.TimeoutBeforeFoundMessage);
- }
-
- [Fact(DisplayName = "WaitForElements waits until cssSelector returns at least one element")]
- [Trait("Category", "async")]
- public async Task Test021()
- {
- var expectedMarkup = "child content
";
- var cut = Render(ps => ps.AddChildContent(expectedMarkup));
-
- var elms = await cut.WaitForElementsAsync("main > p");
-
- elms.MarkupMatches(expectedMarkup);
- }
-
- [Fact(DisplayName = "WaitForElements throws exception after timeout when cssSelector does not result in matching elements")]
- [Trait("Category", "async")]
- public async Task Test022()
- {
- var cut = Render();
-
- var expected = await Should.ThrowAsync(async () =>
- await cut.WaitForElementsAsync("#notHereElm", WaitForTestTimeout));
-
- expected.Message.ShouldStartWith(WaitForElementsHelper.TimeoutBeforeFoundMessage);
- expected.InnerException.ShouldBeNull();
- }
-
- [Fact(DisplayName = "WaitForElements with specific count N throws exception after timeout when cssSelector does not result in N matching elements")]
- [Trait("Category", "async")]
- public async Task Test023()
- {
- var cut = Render();
-
- var expected = await Should.ThrowAsync(async () =>
- await cut.WaitForElementsAsync("#notHereElm", 2, WaitForTestTimeout));
-
- expected.Message.ShouldStartWith(string.Format(CultureInfo.InvariantCulture, WaitForElementsHelper.TimeoutBeforeFoundWithCountMessage, 2));
- expected.InnerException.ShouldBeNull();
- }
-
- [Fact(DisplayName = "WaitForElements with specific count N waits until cssSelector returns at exact N elements")]
- [Trait("Category", "async")]
- public async Task Test024()
- {
- var expectedMarkup = "child content
child content
child content
";
- var cut = Render(ps => ps.AddChildContent(expectedMarkup));
-
- var elms = await cut.WaitForElementsAsync("main > p", matchElementCount: 3);
-
- elms.MarkupMatches(expectedMarkup);
- }
-
- [Fact(DisplayName = "WaitForElements with specific count 0 waits until cssSelector returns at exact zero elements")]
- [Trait("Category", "async")]
- public async Task Test025()
- {
- var expectedMarkup = "child content
";
- var cut = Render(ps => ps.AddChildContent(expectedMarkup));
-
- var elms = await cut.WaitForElementsAsync("main > p", matchElementCount: 0);
-
- elms.ShouldBeEmpty();
- }
-}
diff --git a/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs
index 052fb3559..312746426 100644
--- a/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs
+++ b/tests/bunit.tests/Extensions/WaitForHelpers/RenderedComponentWaitForElementsHelperExtensionsTest.cs
@@ -2,98 +2,92 @@
namespace Bunit.Extensions.WaitForHelpers;
-public class RenderedComponentWaitForElementsHelperExtensionsTest : BunitContext
+public class RenderedComponentWaitForElementsHelperExtensions : BunitContext
{
private readonly static TimeSpan WaitForTestTimeout = TimeSpan.FromMilliseconds(5);
- public RenderedComponentWaitForElementsHelperExtensionsTest(ITestOutputHelper testOutput)
+ public RenderedComponentWaitForElementsHelperExtensions(ITestOutputHelper testOutput)
{
BunitContext.DefaultWaitTimeout = TimeSpan.FromSeconds(30);
Services.AddXunitLogger(testOutput);
}
[Fact(DisplayName = "WaitForElement waits until cssSelector returns at a element")]
- [Trait("Category", "sync")]
- public void Test001()
+ public async Task Test001()
{
var expectedMarkup = "child content
";
var cut = Render(ps => ps.AddChildContent(expectedMarkup));
- var elm = cut.WaitForElement("main > p");
+ var elm = await cut.FindAllAsync("main > p");
elm.MarkupMatches(expectedMarkup);
}
[Fact(DisplayName = "WaitForElement throws exception after timeout when cssSelector does not result in matching element")]
- [Trait("Category", "sync")]
- public void Test002()
+ public async Task Test002()
{
var cut = Render();
- var expected = Should.Throw(() =>
- cut.WaitForElement("#notHereElm", WaitForTestTimeout));
+ var expected = await Should.ThrowAsync(async () =>
+ await cut.FindAllAsync("#notHereElm", WaitForTestTimeout));
expected.Message.ShouldStartWith(WaitForElementHelper.TimeoutBeforeFoundMessage);
}
[Fact(DisplayName = "WaitForElements waits until cssSelector returns at least one element")]
- [Trait("Category", "sync")]
- public void Test021()
+ public async Task Test021()
{
var expectedMarkup = "child content
";
var cut = Render(ps => ps.AddChildContent(expectedMarkup));
- var elms = cut.WaitForElements("main > p");
+ var elms = await cut.FindAllAsync("main > p");
elms.MarkupMatches(expectedMarkup);
}
[Fact(DisplayName = "WaitForElements throws exception after timeout when cssSelector does not result in matching elements")]
- [Trait("Category", "sync")]
- public void Test022()
+ [Trait("Category", "async")]
+ public async Task Test022()
{
var cut = Render();
- var expected = Should.Throw(() =>
- cut.WaitForElements("#notHereElm", WaitForTestTimeout));
+ var expected = await Should.ThrowAsync(async () =>
+ await cut.FindAllAsync("#notHereElm", WaitForTestTimeout));
expected.Message.ShouldStartWith(WaitForElementsHelper.TimeoutBeforeFoundMessage);
expected.InnerException.ShouldBeNull();
}
[Fact(DisplayName = "WaitForElements with specific count N throws exception after timeout when cssSelector does not result in N matching elements")]
- [Trait("Category", "sync")]
- public void Test023()
+ public async Task Test023()
{
var cut = Render();
- var expected = Should.Throw(() =>
- cut.WaitForElements("#notHereElm", 2, WaitForTestTimeout));
+ var expected = await Should.ThrowAsync(async () =>
+ await cut.FindAllAsync("#notHereElm", 2, WaitForTestTimeout));
expected.Message.ShouldStartWith(string.Format(CultureInfo.InvariantCulture, WaitForElementsHelper.TimeoutBeforeFoundWithCountMessage, 2));
expected.InnerException.ShouldBeNull();
}
[Fact(DisplayName = "WaitForElements with specific count N waits until cssSelector returns at exact N elements")]
- [Trait("Category", "sync")]
- public void Test024()
+ public async Task Test024()
{
var expectedMarkup = "child content
child content
child content
";
var cut = Render(ps => ps.AddChildContent(expectedMarkup));
- var elms = cut.WaitForElements("main > p", matchElementCount: 3);
+ var elms = await cut.FindAllAsync("main > p", matchElementCount: 3);
elms.MarkupMatches(expectedMarkup);
}
[Fact(DisplayName = "WaitForElements with specific count 0 waits until cssSelector returns at exact zero elements")]
- [Trait("Category", "sync")]
- public void Test025()
+ public async Task Test025()
{
var expectedMarkup = "child content
";
var cut = Render(ps => ps.AddChildContent(expectedMarkup));
- var elms = cut.WaitForElements("main > p", matchElementCount: 0);
+ var elms = await cut.FindAllAsync("main > p", matchElementCount: 0);
elms.ShouldBeEmpty();
}
diff --git a/tests/bunit.tests/bunit.tests.csproj b/tests/bunit.tests/bunit.tests.csproj
index 45f6e8727..e39baec4b 100644
--- a/tests/bunit.tests/bunit.tests.csproj
+++ b/tests/bunit.tests/bunit.tests.csproj
@@ -14,5 +14,9 @@
+
+
+
+
\ No newline at end of file