-
-
Notifications
You must be signed in to change notification settings - Fork 116
Description
Describe the bug
When a Razor component contains a DynamicComponent
and its type gets changed in a click event, other elements with @ref
element references lose their ReferenceCaptureId
and they get rendered as empty blazor:elementReference=""
(not necessarily all other elements, sometimes just some of them).
When the exact same component is rendered in a full Blazor Server application, this does not happen, the id is rendered e.g. as _bl_75ef2312-3b13-4dfe-925b-b29a10026a50=""
(with the Guid in the attribute name) and stays constant.
Example:
Testing this component:
@page "/dynamic"
<h3 @ref="title">DynamicContainer</h3>
<DynamicComponent Type="@pageType"></DynamicComponent>
<button @onclick="@ChangeDynamic" @ref="button" id="button">ChangeDynamic</button>
@code {
private Type pageType = typeof(ComponentA);
public ElementReference title;
public ElementReference button;
private void ChangeDynamic()
{
pageType = (pageType == typeof(ComponentA)) ? typeof(ComponentB) : typeof(ComponentA);
}
}
With this test:
[Fact(DisplayName = "Changing a DynamicComponent type should not null out the ReferenceCaptureId of other elements")]
public void Test001()
{
var cut = RenderComponent<DynamicContainer>();
output.WriteLine($"Before changing DynamicComponent: {cut.Markup}");
// All @ref elements have a blazor:elementReference GUID
Guid.Parse(GetRefRerenceCaptureId(cut.Markup, "h3"));
Guid.Parse(GetRefRerenceCaptureId(cut.Markup, "button"));
cut.Find("#button").Click();
output.WriteLine($"After changing DynamicComponent: {cut.Markup}");
// Issue: The @ref elements have an empty blazor:elementReference, thus this throws now:
Guid.Parse(GetRefRerenceCaptureId(cut.Markup, "h3"));
Guid.Parse(GetRefRerenceCaptureId(cut.Markup, "button"));
}
// Extract the blazor:elementReference Id string for a HTML element
private string GetRefRerenceCaptureId(string markup, string element)
{
var re = new Regex($"<{element}.*blazor:elementReference=\"([^\"]+).*");
var match = re.Match(markup);
}
Results in this output:
Output:
Before changing DynamicComponent: <h3 blazor:elementReference="644bd20d-ad50-47c1-a183-92376a40134a">DynamicContainer</h3>
<DynamicComponent Type="Bunit.TestAssets.SampleComponents.DynamicComponents.ComponentA"></DynamicComponent>
<button blazor:onclick="1" id="button" blazor:elementReference="552d73b0-5783-41c7-a0c9-3053dfe20d62">ChangeDynamic</button>
After changing DynamicComponent: <h3 blazor:elementReference="">DynamicContainer</h3>
<DynamicComponent Type="Bunit.TestAssets.SampleComponents.DynamicComponents.ComponentB"></DynamicComponent>
<button blazor:onclick="1" id="button" blazor:elementReference="">ChangeDynamic</button>
Expected behavior:
The TestContext.RenderComponent()
should exhibit the same behavior as a Blazor Server application and leave the ReferenceCaptureId
in place when a DynamicComponent
gets rerendered due to a type change.
Version info:
- bUnit version: 1.9.8
- .NET Runtime and Blazor version: 6
- OS type and version: Windows 10
Additional context:
The described problem was first encountered in the Blazor part of https://github.com/toniarnold/aspnettest in the asptest.blazor.bunit
sample test of the asp.blazor
project with bUnit 1.8.15. There the Id
is used to Find
an element, which works with Selenium in a Blazor Server application, but fails with bUnit: It seems that only the Id of a button below a DynamicComponent
gets nulled out. The other references in the test https://github.com/toniarnold/aspnettest/blob/master/src/asptest.blazor.bunit/CalculatorTest/CalculateTest.razor remain reachable in that case.
I've submitted a pull request #748 which exposes the issue with above test case.