diff --git a/src/Components/Web.JS/src/Boot.Server.ts b/src/Components/Web.JS/src/Boot.Server.ts index 824c12546963..307e8e9eed4c 100644 --- a/src/Components/Web.JS/src/Boot.Server.ts +++ b/src/Components/Web.JS/src/Boot.Server.ts @@ -10,15 +10,19 @@ import { DotNet } from '@microsoft/dotnet-js-interop'; import { InitialRootComponentsList } from './Services/InitialRootComponentsList'; import { JSEventRegistry } from './Services/JSEventRegistry'; +type BlazorServerStartOptions = Partial & { circuit?: Partial }; + let started = false; -function boot(userOptions?: Partial): Promise { +function boot(userOptions?: BlazorServerStartOptions): Promise { if (started) { throw new Error('Blazor has already started.'); } started = true; - const configuredOptions = resolveOptions(userOptions); + // Accept the `circuit` property from the blazor.web.js options format + const normalizedOptions = userOptions?.circuit ?? userOptions; + const configuredOptions = resolveOptions(normalizedOptions); setCircuitOptions(Promise.resolve(configuredOptions || {})); JSEventRegistry.create(Blazor); diff --git a/src/Components/Web.JS/src/Boot.WebAssembly.ts b/src/Components/Web.JS/src/Boot.WebAssembly.ts index a1b106b924c2..df014548cf08 100644 --- a/src/Components/Web.JS/src/Boot.WebAssembly.ts +++ b/src/Components/Web.JS/src/Boot.WebAssembly.ts @@ -12,15 +12,19 @@ import { InitialRootComponentsList } from './Services/InitialRootComponentsList' import { JSEventRegistry } from './Services/JSEventRegistry'; import { printErr } from './Platform/Mono/MonoPlatform'; +type BlazorWebAssemblyStartOptions = Partial & { webAssembly?: Partial }; + let started = false; -async function boot(options?: Partial): Promise { +async function boot(options?: BlazorWebAssemblyStartOptions): Promise { if (started) { throw new Error('Blazor has already started.'); } started = true; - setWebAssemblyOptions(Promise.resolve(options || {})); + // Accept the `webAssembly` property from the blazor.web.js options format + const normalizedOptions = options?.webAssembly ?? options ?? {}; + setWebAssemblyOptions(Promise.resolve(normalizedOptions)); JSEventRegistry.create(Blazor); const webAssemblyComponents = discoverComponents(document, 'webassembly') as WebAssemblyComponentDescriptor[]; diff --git a/src/Components/test/E2ETest/ServerExecutionTests/ServerNestedOptionsTest.cs b/src/Components/test/E2ETest/ServerExecutionTests/ServerNestedOptionsTest.cs new file mode 100644 index 000000000000..05d9416fdac1 --- /dev/null +++ b/src/Components/test/E2ETest/ServerExecutionTests/ServerNestedOptionsTest.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using BasicTestApp; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using OpenQA.Selenium; +using TestServer; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETest.ServerExecutionTests; + +public class ServerNestedOptionsTest : ServerTestBase> +{ + public ServerNestedOptionsTest( + BrowserFixture browserFixture, + BasicTestAppServerSiteFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + } + + protected override void InitializeAsyncCore() + { + Navigate($"{ServerPathBase}/nestedCircuitOptions"); + } + + [Fact] + public void NestedCircuitOptionsAreAccepted() + { + var appElement = Browser.MountTestComponent(); + var countDisplayElement = appElement.FindElement(By.TagName("p")); + Browser.Equal("Current count: 0", () => countDisplayElement.Text); + + appElement.FindElement(By.TagName("button")).Click(); + Browser.Equal("Current count: 1", () => countDisplayElement.Text); + } +} diff --git a/src/Components/test/E2ETest/Tests/WebAssemblyNestedOptionsTest.cs b/src/Components/test/E2ETest/Tests/WebAssemblyNestedOptionsTest.cs new file mode 100644 index 000000000000..a94df61cf823 --- /dev/null +++ b/src/Components/test/E2ETest/Tests/WebAssemblyNestedOptionsTest.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using BasicTestApp; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure; +using Microsoft.AspNetCore.Components.E2ETest.Infrastructure.ServerFixtures; +using Microsoft.AspNetCore.E2ETesting; +using OpenQA.Selenium; +using Xunit.Abstractions; + +namespace Microsoft.AspNetCore.Components.E2ETest.Tests; + +public class WebAssemblyNestedOptionsTest : ServerTestBase> +{ + public WebAssemblyNestedOptionsTest( + BrowserFixture browserFixture, + BlazorWasmTestAppFixture serverFixture, + ITestOutputHelper output) + : base(browserFixture, serverFixture, output) + { + _serverFixture.PathBase = "/subdir"; + } + + protected override void InitializeAsyncCore() + { + base.InitializeAsyncCore(); + + // Navigate with query parameter to trigger nested options format + Navigate($"{ServerPathBase}?nested-options=true"); + Browser.MountTestComponent(); + } + + [Fact] + public void NestedWebAssemblyOptionsAreAccepted() + { + var element = Browser.Exists(By.Id("environment")); + Browser.Equal("true", () => element.Text); + } +} diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html index 9506d48c434e..3b5f3f8021f0 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html @@ -63,11 +63,25 @@ document.body.append(element); } - Blazor.start({ - configureRuntime: dotnet => { - dotnet.withEnvironmentVariable("CONFIGURE_RUNTIME", "true"); - } - }); + // Support both top-level and nested options format + // The nested format matches what blazor.web.js uses + const useNestedFormat = location.search.indexOf('nested-options=true') !== -1; + + if (useNestedFormat) { + Blazor.start({ + webAssembly: { + configureRuntime: dotnet => { + dotnet.withEnvironmentVariable("CONFIGURE_RUNTIME", "true"); + } + } + }); + } else { + Blazor.start({ + configureRuntime: dotnet => { + dotnet.withEnvironmentVariable("CONFIGURE_RUNTIME", "true"); + } + }); + } })(); diff --git a/src/Components/test/testassets/Components.TestServer/Pages/NestedCircuitOptions.cshtml b/src/Components/test/testassets/Components.TestServer/Pages/NestedCircuitOptions.cshtml new file mode 100644 index 000000000000..e05c2d7f889d --- /dev/null +++ b/src/Components/test/testassets/Components.TestServer/Pages/NestedCircuitOptions.cshtml @@ -0,0 +1,33 @@ +@page "/nestedCircuitOptions" +@addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers" + + + + + Basic test app - Nested Circuit Options + + + + + + + + +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + +