Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Components/Server/src/Circuits/CircuitFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public async ValueTask<CircuitHost> CreateCircuitHostAsync(
resourceCollection);

circuitActivitySource.Init(new Infrastructure.Server.ComponentsActivityLinkStore(renderer));
renderer.GetOrCreateWebRootComponentManager();

// In Blazor Server we have already restored the app state, so we can get the handlers from DI.
// In Blazor Web the state is provided in the first call to UpdateRootComponents, so we need to
Expand Down
42 changes: 42 additions & 0 deletions src/Components/test/E2ETest/Tests/StatePersistanceJSRootTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Components.TestServer.RazorComponents;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure;
using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures;
using Microsoft.AspNetCore.Components.E2ETests.ServerRenderingTests;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.E2ETesting;
using OpenQA.Selenium;
using TestServer;
using Xunit.Abstractions;

namespace Microsoft.AspNetCore.Components.E2ETests.Tests;

// These tests are for Blazor Web implementation
// For Blazor Server and Webassembly, check SaveStateTest.cs
public class StatePersistanceJSRootTest : ServerTestBase<BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup<App>>>
{
public StatePersistanceJSRootTest(
BrowserFixture browserFixture,
BasicTestAppServerSiteFixture<RazorComponentEndpointsStartup<App>> serverFixture,
ITestOutputHelper output)
: base(browserFixture, serverFixture, output)
{
serverFixture.AdditionalArguments.AddRange("--RegisterDynamicJSRootComponent", "true");
}

[Theory]
[InlineData("ServerNonPrerendered")]
[InlineData("WebAssemblyNonPrerendered")]
public void PersistentStateIsSupportedInDynamicJSRoots(string renderMode)
{
Navigate($"subdir/WasmMinimal/dynamic-js-root.html?renderMode={renderMode}");

Browser.Equal("Counter", () => Browser.Exists(By.TagName("h1")).Text);
Browser.Equal("Current count: 0", () => Browser.Exists(By.CssSelector("p[role='status']")).Text);

Browser.Click(By.CssSelector("button.btn-primary"));
Browser.Equal("Current count: 1", () => Browser.Exists(By.CssSelector("p[role='status']")).Text);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public static async Task Main(string[] args)
["Server authentication"] = (BuildWebHost<ServerAuthenticationStartup>(CreateAdditionalArgs(args)), "/subdir"),
["CORS (WASM)"] = (BuildWebHost<CorsStartup>(CreateAdditionalArgs(args)), "/subdir"),
["Prerendering (Server-side)"] = (BuildWebHost<PrerenderedStartup>(CreateAdditionalArgs(args)), "/prerendered"),
["Razor Component Endpoints"] = (BuildWebHost<RazorComponentEndpointsStartup<Components.TestServer.RazorComponents.App>>(CreateAdditionalArgs(args)), "/subdir"),
["Razor Component Endpoints"] = (BuildWebHost<RazorComponentEndpointsStartup<App>>(CreateAdditionalArgs(args)), "/subdir"),
["Razor Component Endpoints with JS Root Component"] = (BuildWebHost<RazorComponentEndpointsStartup<App>>(CreateAdditionalArgs([.. args, "--RegisterDynamicJSRootComponent", "true"])), "/subdir"),
["Deferred component content (Server-side)"] = (BuildWebHost<DeferredComponentContentStartup>(CreateAdditionalArgs(args)), "/deferred-component-content"),
["Locked navigation (Server-side)"] = (BuildWebHost<LockedNavigationStartup>(CreateAdditionalArgs(args)), "/locked-navigation"),
["Client-side with fallback"] = (BuildWebHost<StartupWithMapFallbackToClientSideBlazor>(CreateAdditionalArgs(args)), "/fallback"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Web;
using Components.TestServer.RazorComponents;
using Components.TestServer.RazorComponents.Pages.Forms;
using Components.TestServer.RazorComponents.Pages.PersistentState;
using Components.TestServer.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Server.Circuits;
Expand Down Expand Up @@ -50,6 +51,10 @@ public void ConfigureServices(IServiceCollection services)
options.DisconnectedCircuitMaxRetained = 0;
options.DetailedErrors = true;
}
if (Configuration.GetValue<bool>("RegisterDynamicJSRootComponent"))
{
options.RootComponents.RegisterForJavaScript<TestContentPackage.PersistentComponents.ComponentWithPersistentState>("dynamic-js-root-counter");
}
})
.AddAuthenticationStateSerialization(options =>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@page "/persistent-state/counter"

<TestContentPackage.PersistentComponents.ComponentWithPersistentState @rendermode="@RenderModeHelper.GetRenderMode(_renderMode)"/>


@code{
[Parameter, SupplyParameterFromQuery(Name = "renderMode")]
public string? RenderModeStr { get; set; }

private RenderModeId _renderMode;

protected override void OnInitialized()
{
if (!string.IsNullOrEmpty(RenderModeStr))
{
_renderMode = RenderModeHelper.ParseRenderMode(RenderModeStr);
}
else
{
throw new ArgumentException("RenderModeStr cannot be null or empty", nameof(RenderModeStr));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<html>
<head>
<base href="/subdir/" />
</head>
<body>
<div id="app">
</div>

<script src="_framework/blazor.server.js" autostart="false"></script>
<script>
Blazor.start().then(() => {
Blazor.rootComponents.add(document.getElementById("app"), "dynamic-js-root-counter", {});
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
[PersistentState] public int currentCount { get; set; }

private void IncrementCount()
{
currentCount++;
}
}
Loading