Add UsePlatformHandler<T> for custom BlazorWebView backends - #34225
Conversation
Adds IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>() extension
method that allows custom platform backends to replace the default
BlazorWebViewHandler while reusing all shared service registrations
from AddMauiBlazorWebView().
This enables scenarios like:
builder.Services.AddMauiBlazorWebView()
.UsePlatformHandler<GtkBlazorWebViewHandler>();
Fixes #34103
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new MAUI BlazorWebView builder extension to allow custom platform backends (e.g., Linux/GTK) to override the default BlazorWebViewHandler while keeping the shared service registrations from AddMauiBlazorWebView().
Changes:
- Introduces
IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()to register a customIBlazorWebViewhandler viaConfigureMauiHandlers. - Updates PublicAPI files to declare the new public extension type and method.
- Adds a core unit test asserting that a second
ConfigureMauiHandlerscall replaces an earlier handler registration.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/BlazorWebView/src/Maui/MauiBlazorWebViewBuilderExtensions.cs | Adds the new UsePlatformHandler<THandler>() public extension method. |
| src/BlazorWebView/src/Maui/PublicAPI/net/PublicAPI.Unshipped.txt | Declares the new public extension type + method in PublicAPI. |
| src/BlazorWebView/src/Maui/PublicAPI/net-android/PublicAPI.Unshipped.txt | Declares the new public extension type + method in PublicAPI (Android TFM). |
| src/BlazorWebView/src/Maui/PublicAPI/net-ios/PublicAPI.Unshipped.txt | Declares the new public extension type + method in PublicAPI (iOS TFM). |
| src/BlazorWebView/src/Maui/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt | Declares the new public extension type + method in PublicAPI (MacCatalyst TFM). |
| src/BlazorWebView/src/Maui/PublicAPI/net-tizen/PublicAPI.Unshipped.txt | Declares the new public extension type + method in PublicAPI (Tizen TFM). |
| src/BlazorWebView/src/Maui/PublicAPI/net-windows/PublicAPI.Unshipped.txt | Declares the new public extension type + method in PublicAPI (Windows TFM). |
| src/Core/tests/UnitTests/Hosting/HostBuilderHandlerTests.cs | Adds a test asserting later ConfigureMauiHandlers registrations override earlier ones. |
…t stub type - Constrain UsePlatformHandler<THandler> to IViewHandler instead of IElementHandler since it registers for IBlazorWebView (an IView) - Replace AlternateButtonHandlerStub with AlternateViewHandlerStub in test to match the IViewStub registration type Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34225Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34225" |
| public static IMauiBlazorWebViewBuilder UsePlatformHandler<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] THandler>( | ||
| this IMauiBlazorWebViewBuilder builder) | ||
| where THandler : IViewHandler | ||
| { | ||
| builder.Services.ConfigureMauiHandlers(handlers => | ||
| handlers.AddHandler<IBlazorWebView, THandler>()); | ||
| return builder; |
There was a problem hiding this comment.
UsePlatformHandler<THandler>() registers the handler via handlers.AddHandler<IBlazorWebView, THandler>(), which ultimately creates handler instances using Activator.CreateInstance(ImplementationType) in MauiFactory. This requires THandler to have a public parameterless constructor; otherwise it will fail at runtime with a MissingMethodException. Consider enforcing this contract with a new() generic constraint, or switch to the factory overload (AddHandler<TType>(Func<IServiceProvider, IElementHandler>)) so handlers with non-parameterless constructors can be created safely.
This comment has been minimized.
This comment has been minimized.
- Add new() constraint to UsePlatformHandler<THandler>() to make the public parameterless constructor requirement explicit at compile time - Add factory-based UsePlatformHandler(Func<IServiceProvider, IElementHandler>) overload for handlers that need dependency injection - Add ArgumentNullException.ThrowIfNull guard on factory parameter - Update all 6 TFM PublicAPI.Unshipped.txt files with new overload - Add FactoryBasedHandlerRegistrationReplacesHandler test Addresses review comment about Activator.CreateInstance requiring parameterless constructors and MauiBot recommendation for DI-friendly handler activation path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🧪 PR Test EvaluationOverall Verdict: The tests verify the underlying handler replacement mechanism but don't directly exercise the new
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34225 — Add Overall VerdictThe two new unit tests validate the general handler-replacement plumbing (that 1. Fix Coverage —
|
| Fix | Test |
|---|---|
MauiBlazorWebViewBuilderExtensions.UsePlatformHandler(THandler)() |
Not tested |
MauiBlazorWebViewBuilderExtensions.UsePlatformHandler(factory) |
Not tested |
handlers.AddHandler(IBlazorWebView, THandler)() called internally |
Tested indirectly (generic overload on different types) |
handlers.AddHandler(IBlazorWebView)(factory) called internally |
Tested indirectly (factory overload on different types) |
The test file is in Core.UnitTests while the fix is in BlazorWebView. The tests verify the Core handler infrastructure — not the BlazorWebView-specific extension methods. If the IBlazorWebView type mapping were accidentally omitted from UsePlatformHandler, no test would catch it.
Recommendations
-
Add direct tests for
UsePlatformHandler— Create a test that callsbuilder.Services.AddMauiBlazorWebView(b => b.UsePlatformHandler(CustomHandlerStub)()), builds the app, resolves the handler forIBlazorWebView, and asserts it is aCustomHandlerStub. Repeat for the factory overload. -
Test the null guard — Add a
[Fact]assertingArgumentNullExceptionis thrown whennullis passed to the factory overload. -
Consider a "replaces default" test — Verify that
UsePlatformHandlerspecifically overwrites theBlazorWebViewHandlerthatAddMauiBlazorWebViewregisters by default, since that is the primary use-case described in the XML docs.
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
dc.services.visualstudio.com
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "dc.services.visualstudio.com"See Network Configuration for more information.
Note
🔒 Integrity filtering filtered 1 item
Integrity filtering activated and filtered the following item during workflow execution.
This happens when a tool call accesses a resource that does not meet the required integrity or secrecy level of the workflow.
- pr:Add UsePlatformHandler<T> for custom BlazorWebView backends #34225 (
pull_request_read: Resource 'pr:Add UsePlatformHandler<T> for custom BlazorWebView backends #34225' has lower integrity than agent requires. Agent would need to drop integrity tags [unapproved:all approved:all] to trust this resource.)
🧪 Test evaluation by Evaluate PR Tests
- Add ArgumentNullException.ThrowIfNull(builder) to both overloads for consistent null validation - Change factory overload parameter from Func<IServiceProvider, IElementHandler> to Func<IServiceProvider, IViewHandler> for type safety consistency with the generic overload's IViewHandler constraint - Update PublicAPI files to reflect the tighter factory signature Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Review Feedback AddressedPushed two commits to address all review feedback: Commit 1:
|
| Finding | Source | Status |
|---|---|---|
Constructor activation trap (missing new()) |
Copilot inline review | ✅ Fixed |
| No DI-friendly registration path | MauiBot AI review | ✅ Fixed (factory overload) |
Missing builder null checks |
Multi-model consensus | ✅ Fixed |
IElementHandler vs IViewHandler mismatch |
Multi-model consensus | ✅ Fixed |
All builds pass. All 25 handler tests pass (including 2 new tests).
Three reviewers (Claude Opus 4.7-xhigh, Claude Sonnet 4.6, GPT-5.5) flagged two shared concerns on the new UsePlatformHandler API: 1. Tests don't actually call UsePlatformHandler. The two existing HostBuilderHandlerTests prove the underlying ConfigureMauiHandlers replacement mechanism with stub types but never exercise the new public BlazorWebView API surface. A typo in MauiBlazorWebViewBuilderExtensions (wrong type argument, wrong service type, missing closure capture) would not be caught. 2. The XML doc on the factory overload claims it 'supports handlers that require dependency injection,' but the IServiceProvider passed by MauiFactory to the factory delegate is the MauiHandlersFactory itself — not the application's root IServiceProvider. It can resolve handler-collection services only. This commit: * Adds two direct device-test Facts in BlazorWebViewTests.Services.cs that call AddMauiBlazorWebView().UsePlatformHandler<T>() / .UsePlatformHandler(factory) and assert the IBlazorWebView handler resolves to the custom type. The stub inherits BlazorWebViewHandler so it satisfies IViewHandler/new() on every device-test target without reimplementing the handler surface. * Tightens the XML docs on both overloads with a <remarks> block explaining the last-registration-wins ordering rule (call after AddMauiBlazorWebView, and call last when downstream libraries may re-invoke AddMauiBlazorWebView). * Clarifies the factory-overload contract so readers don't expect arbitrary app-level DI to flow through the factory delegate's IServiceProvider. No public API surface changes — only XML docs and tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GPT-5.5 reviewer caught a build-breaking CS1574 introduced by the previous commit's <remarks> block: the file does not 'using Microsoft.Extensions.DependencyInjection;', so '<see cref="IServiceCollection"/>' fails to resolve and breaks docs compilation. Fully qualify the cref to match the file's existing pattern (see the cref to BlazorWebViewServiceCollectionExtensions.AddMauiBlazorWebView elsewhere in this file, which uses 'M:Microsoft.Extensions.DependencyInjection.BlazorWebViewServiceCollectionExtensions...'). Verified: 'dotnet build src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj -f net10.0' now succeeds with 0 warnings, 0 errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🤖 Multi-Model Code Review — Round 2 ConvergenceI ran an adversarial multi-model code review of this PR using three top-tier reviewers in parallel: Claude Opus 4.7 (xhigh reasoning), Claude Sonnet 4.6, and GPT-5.5. Each followed the Round 1 — divergent findings
Multi-model agreement: all three reviewers independently flagged that the new tests verified the underlying Fixes applied
Round 2 — convergence
Final consensus: ✅ LGTM across all three models with high confidence. Final PR state
Items intentionally not addressed
Reviewed with Claude Opus 4.7 (xhigh) + Claude Sonnet 4.6 + GPT-5.5 in parallel via the GitHub Copilot CLI multi-model review workflow. |
|
/azp run maui-pr-uitests, maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
|
/review -b feature/enhanced-reviewer -p android |
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@Redth — new AI review results are available based on this last commit:
f146082.
Fix unresolved cref to IServiceCollection in XML doc To request a fresh review after new comments or commits, comment/review rerun.
Review Sessions — click to expand
Gate — Test Before & After Fix
Gate Result: ❌ FAILED
Platform: ANDROID · Base: main · Merge base: e904e900
🩺 Fix breaks tests — one or more tests fail with the fix applied, and none of the failures are resolved by the fix.
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📱 BlazorWebViewTests (UsePlatformHandlerGenericReplacesDefaultBlazorWebViewHandler, UsePlatformHandlerFactoryReplacesDefaultBlazorWebViewHandler) Category=BlazorWebView |
✅ FAIL — 983s | ❌ FAIL — 958s |
🧪 HostBuilderHandlerTests HostBuilderHandlerTests |
❌ PASS — 157s | ✅ PASS — 21s |
🔴 Without fix — 📱 BlazorWebViewTests (UsePlatformHandlerGenericReplacesDefaultBlazorWebViewHandler, UsePlatformHandlerFactoryReplacesDefaultBlazorWebViewHandler): FAIL ✅ · 983s
(truncated to last 15,000 chars)
AndroidX.Navigation.Runtime.Android.dll -> Xamarin.AndroidX.Navigation.Runtime.Android.dll.so
[58/137] Xamarin.AndroidX.Navigation.UI.dll -> Xamarin.AndroidX.Navigation.UI.dll.so
[59/137] Xamarin.AndroidX.RecyclerView.dll -> Xamarin.AndroidX.RecyclerView.dll.so
[60/137] Xamarin.AndroidX.SavedState.SavedState.Android.dll -> Xamarin.AndroidX.SavedState.SavedState.Android.dll.so
[136/137] Mono.Android.dll -> Mono.Android.dll.so
[61/137] Xamarin.AndroidX.SwipeRefreshLayout.dll -> Xamarin.AndroidX.SwipeRefreshLayout.dll.so
[62/137] Xamarin.AndroidX.ViewPager.dll -> Xamarin.AndroidX.ViewPager.dll.so
[63/137] Xamarin.AndroidX.ViewPager2.dll -> Xamarin.AndroidX.ViewPager2.dll.so
[64/137] Xamarin.Google.Android.Material.dll -> Xamarin.Google.Android.Material.dll.so
[65/137] Xamarin.Kotlin.StdLib.dll -> Xamarin.Kotlin.StdLib.dll.so
[66/137] Xamarin.KotlinX.Coroutines.Core.Jvm.dll -> Xamarin.KotlinX.Coroutines.Core.Jvm.dll.so
[67/137] Xamarin.KotlinX.Serialization.Core.Jvm.dll -> Xamarin.KotlinX.Serialization.Core.Jvm.dll.so
[68/137] xunit.abstractions.dll -> xunit.abstractions.dll.so
[69/137] xunit.assert.dll -> xunit.assert.dll.so
[70/137] xunit.core.dll -> xunit.core.dll.so
[71/137] xunit.execution.dotnet.dll -> xunit.execution.dotnet.dll.so
[72/137] xunit.runner.utility.netcoreapp10.dll -> xunit.runner.utility.netcoreapp10.dll.so
[137/137] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
[73/137] System.Collections.Concurrent.dll -> System.Collections.Concurrent.dll.so
[74/137] System.Collections.Immutable.dll -> System.Collections.Immutable.dll.so
[75/137] System.Collections.NonGeneric.dll -> System.Collections.NonGeneric.dll.so
[76/137] System.Collections.Specialized.dll -> System.Collections.Specialized.dll.so
[77/137] System.Collections.dll -> System.Collections.dll.so
[78/137] System.ComponentModel.Primitives.dll -> System.ComponentModel.Primitives.dll.so
[79/137] System.ComponentModel.TypeConverter.dll -> System.ComponentModel.TypeConverter.dll.so
[80/137] System.ComponentModel.dll -> System.ComponentModel.dll.so
[81/137] System.Console.dll -> System.Console.dll.so
[82/137] System.Diagnostics.Debug.dll -> System.Diagnostics.Debug.dll.so
[83/137] System.Diagnostics.DiagnosticSource.dll -> System.Diagnostics.DiagnosticSource.dll.so
[84/137] System.Diagnostics.Process.dll -> System.Diagnostics.Process.dll.so
[85/137] System.Diagnostics.Tools.dll -> System.Diagnostics.Tools.dll.so
[86/137] System.Diagnostics.TraceSource.dll -> System.Diagnostics.TraceSource.dll.so
[87/137] System.Diagnostics.Tracing.dll -> System.Diagnostics.Tracing.dll.so
[88/137] System.Drawing.Primitives.dll -> System.Drawing.Primitives.dll.so
[89/137] System.Drawing.dll -> System.Drawing.dll.so
[90/137] System.Formats.Asn1.dll -> System.Formats.Asn1.dll.so
[91/137] System.Globalization.dll -> System.Globalization.dll.so
[92/137] System.IO.Compression.Brotli.dll -> System.IO.Compression.Brotli.dll.so
[93/137] System.IO.Compression.dll -> System.IO.Compression.dll.so
[94/137] System.IO.FileSystem.Watcher.dll -> System.IO.FileSystem.Watcher.dll.so
[95/137] System.IO.FileSystem.dll -> System.IO.FileSystem.dll.so
[96/137] System.IO.Pipelines.dll -> System.IO.Pipelines.dll.so
[97/137] System.IO.dll -> System.IO.dll.so
[98/137] System.Linq.Expressions.dll -> System.Linq.Expressions.dll.so
[99/137] System.Linq.dll -> System.Linq.dll.so
[100/137] System.Memory.dll -> System.Memory.dll.so
[101/137] System.Net.Http.dll -> System.Net.Http.dll.so
[102/137] System.Net.NameResolution.dll -> System.Net.NameResolution.dll.so
[103/137] System.Net.Primitives.dll -> System.Net.Primitives.dll.so
[104/137] System.Net.Requests.dll -> System.Net.Requests.dll.so
[105/137] System.Net.Sockets.dll -> System.Net.Sockets.dll.so
[106/137] System.Numerics.Vectors.dll -> System.Numerics.Vectors.dll.so
[107/137] System.ObjectModel.dll -> System.ObjectModel.dll.so
[108/137] System.Private.Uri.dll -> System.Private.Uri.dll.so
[109/137] System.Private.Xml.Linq.dll -> System.Private.Xml.Linq.dll.so
[110/137] System.Private.Xml.dll -> System.Private.Xml.dll.so
[111/137] System.Reflection.Extensions.dll -> System.Reflection.Extensions.dll.so
[112/137] System.Reflection.TypeExtensions.dll -> System.Reflection.TypeExtensions.dll.so
[113/137] System.Reflection.dll -> System.Reflection.dll.so
[114/137] System.Runtime.Extensions.dll -> System.Runtime.Extensions.dll.so
[115/137] System.Runtime.InteropServices.RuntimeInformation.dll -> System.Runtime.InteropServices.RuntimeInformation.dll.so
[116/137] System.Runtime.InteropServices.dll -> System.Runtime.InteropServices.dll.so
[117/137] System.Runtime.Loader.dll -> System.Runtime.Loader.dll.so
[118/137] System.Runtime.Numerics.dll -> System.Runtime.Numerics.dll.so
[119/137] System.Runtime.dll -> System.Runtime.dll.so
[120/137] System.Security.Cryptography.dll -> System.Security.Cryptography.dll.so
[121/137] System.Text.Encoding.dll -> System.Text.Encoding.dll.so
[122/137] System.Text.Encodings.Web.dll -> System.Text.Encodings.Web.dll.so
[123/137] System.Text.Json.dll -> System.Text.Json.dll.so
[124/137] System.Text.RegularExpressions.dll -> System.Text.RegularExpressions.dll.so
[125/137] System.Threading.Tasks.dll -> System.Threading.Tasks.dll.so
[126/137] System.Threading.Thread.dll -> System.Threading.Thread.dll.so
[127/137] System.Threading.ThreadPool.dll -> System.Threading.ThreadPool.dll.so
[128/137] System.Threading.dll -> System.Threading.dll.so
[129/137] System.Xml.Linq.dll -> System.Xml.Linq.dll.so
[130/137] System.Xml.ReaderWriter.dll -> System.Xml.ReaderWriter.dll.so
[131/137] System.Xml.XDocument.dll -> System.Xml.XDocument.dll.so
[132/137] System.dll -> System.dll.so
[133/137] netstandard.dll -> netstandard.dll.so
[134/137] Java.Interop.dll -> Java.Interop.dll.so
[135/137] Mono.Android.Runtime.dll -> Mono.Android.Runtime.dll.so
[136/137] Mono.Android.dll -> Mono.Android.dll.so
[137/137] System.Private.CoreLib.dll -> System.Private.CoreLib.dll.so
Build succeeded.
/home/vsts/work/1/s/src/BlazorWebView/src/Maui/MauiBlazorWebViewBuilderExtensions.cs(11,22): warning RS0016: Symbol 'Microsoft.AspNetCore.Components.WebView.Maui.MauiBlazorWebViewBuilderExtensions' is not part of the declared public API (https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) [/home/vsts/work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj::TargetFramework=net10.0-android36.0]
/home/vsts/work/1/s/src/BlazorWebView/src/Maui/MauiBlazorWebViewBuilderExtensions.cs(32,43): warning RS0016: Symbol 'static Microsoft.AspNetCore.Components.WebView.Maui.MauiBlazorWebViewBuilderExtensions.UsePlatformHandler<THandler>(this Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder! builder) -> Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder!' is not part of the declared public API (https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) [/home/vsts/work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj::TargetFramework=net10.0-android36.0]
/home/vsts/work/1/s/src/BlazorWebView/src/Maui/MauiBlazorWebViewBuilderExtensions.cs(64,43): warning RS0016: Symbol 'static Microsoft.AspNetCore.Components.WebView.Maui.MauiBlazorWebViewBuilderExtensions.UsePlatformHandler(this Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder! builder, System.Func<System.IServiceProvider!, Microsoft.Maui.IViewHandler!>! factory) -> Microsoft.AspNetCore.Components.WebView.Maui.IMauiBlazorWebViewBuilder!' is not part of the declared public API (https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) [/home/vsts/work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj::TargetFramework=net10.0-android36.0]
3 Warning(s)
0 Error(s)
Time Elapsed 00:10:04.43
[11.0.0-prerelease.26230.4+92962e5c46ac08a66ded4c5696209cc60f1a232f] XHarness command issued: android test --app /home/vsts/work/1/s/artifacts/bin/MauiBlazorWebView.DeviceTests/Release/net10.0-android/com.microsoft.maui.mauiblazorwebview.devicetests-Signed.apk --package-name com.microsoft.maui.mauiblazorwebview.devicetests --device-id emulator-5554 -o artifacts/log --timeout 01:00:00 -v --arg TestFilter=Category=BlazorWebView
�[40m�[37mdbug�[39m�[22m�[49m: ADBRunner using ADB.exe supplied from /home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/tools/net10.0/any/../../../runtimes/any/native/adb/linux/adb
�[40m�[37mdbug�[39m�[22m�[49m: Full resolved path:'/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb'
�[40m�[32minfo�[39m�[22m�[49m: Will attempt to find device supporting architectures: 'arm64-v8a', 'x86_64'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb start-server'
�[40m�[37mdbug�[39m�[22m�[49m:
�[40m�[32minfo�[39m�[22m�[49m: Finding attached devices/emulators...
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb devices -l'
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 possible devices
�[40m�[37mdbug�[39m�[22m�[49m: Evaluating output line for device serial: emulator-5554 device product:sdk_gphone_x86_64 model:sdk_gphone_x86_64 device:generic_x86_64_arm64 transport_id:3
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell getprop ro.product.cpu.abilist'
�[40m�[37mdbug�[39m�[22m�[49m: Found 1 possible devices. Using 'emulator-5554'
�[40m�[32minfo�[39m�[22m�[49m: Active Android device set to serial 'emulator-5554'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop ro.product.cpu.abi'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop ro.build.version.sdk'
�[40m�[32minfo�[39m�[22m�[49m: Waiting for device to be available (max 5 minutes)
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 wait-for-device'
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 -s emulator-5554 shell getprop sys.boot_completed'
�[40m�[37mdbug�[39m�[22m�[49m: sys.boot_completed = '1'
�[40m�[37mdbug�[39m�[22m�[49m: Waited 0 seconds for device boot completion
�[40m�[37mdbug�[39m�[22m�[49m: Working with emulator-5554 (API 30)
�[40m�[37mdbug�[39m�[22m�[49m: Check current adb install and/or package verification settings
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell settings get global verifier_verify_adb_installs'
�[40m�[37mdbug�[39m�[22m�[49m: verifier_verify_adb_installs = 0
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 shell settings get global package_verifier_enable'
�[40m�[37mdbug�[39m�[22m�[49m: package_verifier_enable =
�[40m�[1m�[33mwarn�[39m�[22m�[49m: Installing debug apks on a device might be rejected with INSTALL_FAILED_VERIFICATION_FAILURE. Make sure to set 'package_verifier_enable' to '0'
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.mauiblazorwebview.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.mauiblazorwebview.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Waiting for command timed out: execution may be compromised
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: -2
Std out:
�[40m�[32minfo�[39m�[22m�[49m: Attempting to install /home/vsts/work/1/s/artifacts/bin/MauiBlazorWebView.DeviceTests/Release/net10.0-android/com.microsoft.maui.mauiblazorwebview.devicetests-Signed.apk
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 install /home/vsts/work/1/s/artifacts/bin/MauiBlazorWebView.DeviceTests/Release/net10.0-android/com.microsoft.maui.mauiblazorwebview.devicetests-Signed.apk'
�[41m�[30mfail�[39m�[22m�[49m: Error:
Exit code: 1
Std out:
Serving...
Performing Incremental Install
cmd: Failure calling service package: Broken pipe (32)
Performing Streamed Install
Std err:
All files should be loaded. Notifying the device.
adb: failed to install /home/vsts/work/1/s/artifacts/bin/MauiBlazorWebView.DeviceTests/Release/net10.0-android/com.microsoft.maui.mauiblazorwebview.devicetests-Signed.apk: cmd: Can't find service: package
�[41m�[1m�[37mcrit�[39m�[22m�[49m: Install failure: Test command cannot continue
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.mauiblazorwebview.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.mauiblazorwebview.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: 20
Std out:
Std err:
cmd: Can't find service: package
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.mauiblazorwebview.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.mauiblazorwebview.devicetests'
�[41m�[30mfail�[39m�[22m�[49m: Error: Exit code: 20
Std out:
Std err:
cmd: Can't find service: package
XHarness exit code: 78 (PACKAGE_INSTALLATION_FAILURE)
Tests completed with exit code: 78
🟢 With fix — 📱 BlazorWebViewTests (UsePlatformHandlerGenericReplacesDefaultBlazorWebViewHandler, UsePlatformHandlerFactoryReplacesDefaultBlazorWebViewHandler): FAIL ❌ · 958s
(truncated to last 15,000 chars)
--
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<<AttachAndRun>g__Run|21_0>d`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<AttachAndRun>d__21`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<>c__DisplayClass72_0`2.<<AttachAndRun>g__Run|0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Maui.IPlatformViewHandler, Microsoft.Maui, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass2_0`1.<<DispatchAsync>b__0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.RunTest(Func`3 test)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.RunUrlResolutionTest(String path, String mode, Action`1 assertion)
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : Execution time: 30.2548012
06-07 12:17:01.087 16496 16900 I DOTNET : Test trait name: Category
06-07 12:17:01.087 16496 16900 I DOTNET : value: BlazorWebView
06-07 12:17:01.087 16496 16900 I DOTNET :
06-07 12:17:01.087 16496 16900 I DOTNET : 18) [FAIL] BlazorWebViewWithoutDispatchFailsToGetScopedServices Test name: BlazorWebViewWithoutDispatchFailsToGetScopedServices
06-07 12:17:01.087 16496 16900 I DOTNET : Assembly: [Microsoft.Maui.MauiBlazorWebView.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
06-07 12:17:01.087 16496 16900 I DOTNET : Exception messages: System.Exception : Waited 30000ms but couldn't get window.Blazor to be non-null *and* have window.__BlazorStarted to be true. Exception stack traces: at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.Retry(Func`1 tryAction, Func`2 createExceptionWithTimeoutMS)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.WaitForWebViewReady(WebView webview)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.<>c__DisplayClass32_0.<<BlazorWebViewWithoutDispatchFailsToGetScopedServices>b__1>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass3_0.<<DispatchAsync>b__0>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass2_0`1.<<DispatchAsync>b__0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.BlazorWebViewWithoutDispatchFailsToGetScopedServices()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : Execution time: 30.0698148
06-07 12:17:01.087 16496 16900 I DOTNET : Test trait name: Category
06-07 12:17:01.087 16496 16900 I DOTNET : value: BlazorWebView
06-07 12:17:01.087 16496 16900 I DOTNET :
06-07 12:17:01.087 16496 16900 I DOTNET : 19) [FAIL] BasicRazorComponentClick Test name: BasicRazorComponentClick
06-07 12:17:01.087 16496 16900 I DOTNET : Assembly: [Microsoft.Maui.MauiBlazorWebView.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
06-07 12:17:01.087 16496 16900 I DOTNET : Exception messages: System.Exception : Waited 30000ms but couldn't get window.Blazor to be non-null *and* have window.__BlazorStarted to be true. Exception stack traces: at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.Retry(Func`1 tryAction, Func`2 createExceptionWithTimeoutMS)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.WaitForWebViewReady(WebView webview)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.<>c__DisplayClass2_0.<<BasicRazorComponentClick>b__1>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass3_0.<<DispatchAsync>b__0>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass2_0`1.<<DispatchAsync>b__0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.BasicRazorComponentClick()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : Execution time: 30.0695581
06-07 12:17:01.087 16496 16900 I DOTNET : Test trait name: Category
06-07 12:17:01.087 16496 16900 I DOTNET : value: BlazorWebView
06-07 12:17:01.087 16496 16900 I DOTNET :
06-07 12:17:01.087 16496 16900 I DOTNET : 20) [FAIL] RequestsCanBeInterceptedAndCustomDataReturnedForDifferentHosts Test name: RequestsCanBeInterceptedAndCustomDataReturnedForDifferentHosts(uriBase: "https://echo.free.beeceptor.com/sample-request") Test case: RequestsCanBeInterceptedAndCustomDataReturnedForDifferentHosts
06-07 12:17:01.087 16496 16900 I DOTNET : Assembly: [Microsoft.Maui.MauiBlazorWebView.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
06-07 12:17:01.087 16496 16900 I DOTNET : Exception messages: System.Exception : Waited 30000ms but couldn't get window.Blazor to be non-null *and* have window.__BlazorStarted to be true. Exception stack traces: at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.Retry(Func`1 tryAction, Func`2 createExceptionWithTimeoutMS)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.WaitForWebViewReady(WebView webview)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.<>c__DisplayClass26_0.<<RunTest>b__1>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.HandlerTestBasement.<>c__DisplayClass20_0.<<AttachAndRun>b__0>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<<AttachAndRun>g__Run|21_0>d`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<AttachAndRun>d__21`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<>c__DisplayClass72_0`2.<<AttachAndRun>g__Run|0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Maui.IPlatformViewHandler, Microsoft.Maui, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass2_0`1.<<DispatchAsync>b__0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.RunTest(Func`3 test)
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : Execution time: 30.2194039
06-07 12:17:01.087 16496 16900 I DOTNET : Test trait name: Category
06-07 12:17:01.087 16496 16900 I DOTNET : value: BlazorWebView
06-07 12:17:01.087 16496 16900 I DOTNET :
06-07 12:17:01.087 16496 16900 I DOTNET : 21) [FAIL] RequestsCanBeInterceptedAndCaseInsensitiveHeadersRead Test name: RequestsCanBeInterceptedAndCaseInsensitiveHeadersRead(uriBase: "https://echo.free.beeceptor.com/sample-request") Test case: RequestsCanBeInterceptedAndCaseInsensitiveHeadersRead
06-07 12:17:01.087 16496 16900 I DOTNET : Assembly: [Microsoft.Maui.MauiBlazorWebView.DeviceTests, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]
06-07 12:17:01.087 16496 16900 I DOTNET : Exception messages: System.Exception : Waited 30000ms but couldn't get window.Blazor to be non-null *and* have window.__BlazorStarted to be true. Exception stack traces: at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.Retry(Func`1 tryAction, Func`2 createExceptionWithTimeoutMS)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.WebViewHelpers.WaitForWebViewReady(WebView webview)
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.<>c__DisplayClass26_0.<<RunTest>b__1>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.HandlerTestBasement.<>c__DisplayClass20_0.<<AttachAndRun>b__0>d.MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<<AttachAndRun>g__Run|21_0>d`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<AttachAndRun>d__21`1[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.DeviceTests.AssertionExtensions.<>c__DisplayClass72_0`2.<<AttachAndRun>g__Run|0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[Microsoft.Maui.IPlatformViewHandler, Microsoft.Maui, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.Dispatching.DispatcherExtensions.<>c__DisplayClass2_0`1.<<DispatchAsync>b__0>d[[System.Boolean, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : at Microsoft.Maui.MauiBlazorWebView.DeviceTests.Elements.BlazorWebViewTests.RunTest(Func`3 test)
06-07 12:17:01.087 16496 16900 I DOTNET : --- End of stack trace from previous location ---
06-07 12:17:01.087 16496 16900 I DOTNET : Execution time: 30.2891763
06-07 12:17:01.087 16496 16900 I DOTNET : Test trait name: Category
06-07 12:17:01.087 16496 16900 I DOTNET : value: BlazorWebView
06-07 12:17:01.087 16496 16900 I DOTNET :
06-07 12:17:01.114 16496 16900 I DOTNET : Xml file was written to the provided writer.
06-07 12:17:01.115 16496 16900 I DOTNET : Tests run: 25 Passed: 3 Inconclusive: 0 Failed: 21 Ignored: 0
�[41m�[30mfail�[39m�[22m�[49m: Non-success instrumentation exit code: 1, expected: 0
�[40m�[32minfo�[39m�[22m�[49m: <<XHARNESS_RESULT_START>>
{
"version": 1,
"machineName": "runnervmm79r7",
"exitCode": 1,
"exitCodeName": "TESTS_FAILED",
"platform": "android",
"instrumentationExitCode": 1,
"device": "emulator-5554",
"deviceOsVersion": "API 30",
"architecture": "x86_64",
"files": [
{
"name": "testResults.xml",
"type": "test-results"
},
{
"name": "adb-logcat-com.microsoft.maui.mauiblazorwebview.devicetests-default.log",
"type": "logcat"
}
]
}
<<XHARNESS_RESULT_END>>
�[40m�[32minfo�[39m�[22m�[49m: Attempting to remove apk 'com.microsoft.maui.mauiblazorwebview.devicetests'..
�[40m�[37mdbug�[39m�[22m�[49m: Executing command: '/home/vsts/.nuget/packages/microsoft.dotnet.xharness.cli/11.0.0-prerelease.26230.4/runtimes/any/native/adb/linux/adb -s emulator-5554 uninstall com.microsoft.maui.mauiblazorwebview.devicetests'
�[40m�[32minfo�[39m�[22m�[49m: Successfully uninstalled com.microsoft.maui.mauiblazorwebview.devicetests
XHarness exit code: 1 (TESTS_FAILED)
Tests completed with exit code: 1
🔴 Without fix — 🧪 HostBuilderHandlerTests: PASS ❌ · 157s
Determining projects to restore...
Restored /home/vsts/work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 1.11 sec).
Restored /home/vsts/work/1/s/src/Core/src/Core.csproj (in 1.27 sec).
Restored /home/vsts/work/1/s/src/TestUtils/src/TestUtils/TestUtils.csproj (in 209 ms).
Restored /home/vsts/work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 214 ms).
Restored /home/vsts/work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 30 ms).
Restored /home/vsts/work/1/s/src/Essentials/src/Essentials.csproj (in 58 ms).
Restored /home/vsts/work/1/s/src/Core/tests/UnitTests/Core.UnitTests.csproj (in 2.04 sec).
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
TestUtils -> /home/vsts/work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
Core.UnitTests -> /home/vsts/work/1/s/artifacts/bin/Core.UnitTests/Debug/net10.0/Microsoft.Maui.UnitTests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Core.UnitTests/Debug/net10.0/Microsoft.Maui.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.14] Discovering: Microsoft.Maui.UnitTests
[xUnit.net 00:00:00.73] Discovered: Microsoft.Maui.UnitTests
[xUnit.net 00:00:00.74] Starting: Microsoft.Maui.UnitTests
Passed HostBuilderThrowsWhenOnlyInterfacesRelatedByInheritanceAreRegistered [82 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: False, retrieveHandlerServiceWithGenerics: True) [6 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: False, retrieveHandlerServiceWithGenerics: False) [< 1 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: True, retrieveHandlerServiceWithGenerics: True) [< 1 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: True, retrieveHandlerServiceWithGenerics: False) [< 1 ms]
Passed FactoryBasedHandlerRegistrationReplacesHandler [1 ms]
Passed SecondConfigureMauiHandlersCallReplacesHandler [< 1 ms]
Passed HostBuilderDoesNotResolveHandlersRegisteredUnderMoreDerivedTypes [< 1 ms]
Passed HostBuilderResolvesToHandlerRegisteredUnderConcreteTypeDespiteAmbiguousInterfacesRegistered [< 1 ms]
Passed HostBuilderWithoutDefaultsDoesNotRegisterMauiHandlersFactory [2 ms]
Passed HostBuilderCanBuildAHost [< 1 ms]
Passed HostBuilderResolvesHandlerRegisteredUnderBaseInterfaceType(baseInterfaceType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+IMyDerivedViewStub)) [2 ms]
Passed HostBuilderResolvesHandlerRegisteredUnderBaseInterfaceType(baseInterfaceType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+IMyBaseViewStub)) [< 1 ms]
Passed HostBuilderResolvesHandlerRegisteredUnderBaseInterfaceType(baseInterfaceType: typeof(Microsoft.Maui.UnitTests.IViewStub)) [< 1 ms]
Passed HostBuilderResolvesToHandlerRegisteredUnderConcreteTypeOverInterfaceType [< 1 ms]
Passed HostBuilderResolvesHandlerTypeForServiceRegisteredWithType [2 ms]
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.ViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.ViewHandlerStub)) [< 1 ms]
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyDerivedViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyBaseHandlerStub)) [2 ms]
[xUnit.net 00:00:01.05] Finished: Microsoft.Maui.UnitTests
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyBaseViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyBaseHandlerStub)) [< 1 ms]
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.IViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.ViewHandlerStub)) [< 1 ms]
Passed HostBuilderCannotResolveHandlerTypeForServiceRegisteredWithFactory [2 ms]
Passed HostBuilderResolvesLastRegisteredHandlerServiceForServiceType [1 ms]
Passed HostBuilderThrowsWhenNoMatchingHandlerServiceTypeIsRegistered [< 1 ms]
Passed HostBuilderResolvesToHandlerRegisteredUnderMostDerivedBaseInterfaceType [2 ms]
Passed HostBuilderWithDefaultsRegistersMauiHandlersFactory [< 1 ms]
Test Run Successful.
Total tests: 25
Passed: 25
Total time: 2.0414 Seconds
🟢 With fix — 🧪 HostBuilderHandlerTests: PASS ✅ · 21s
Determining projects to restore...
Restored /home/vsts/work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 1.03 sec).
Restored /home/vsts/work/1/s/src/Essentials/src/Essentials.csproj (in 1.04 sec).
Restored /home/vsts/work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 298 ms).
Restored /home/vsts/work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 88 ms).
Restored /home/vsts/work/1/s/src/Core/src/Core.csproj (in 479 ms).
2 of 7 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14306458
Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
TestUtils -> /home/vsts/work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
Core.UnitTests -> /home/vsts/work/1/s/artifacts/bin/Core.UnitTests/Debug/net10.0/Microsoft.Maui.UnitTests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Core.UnitTests/Debug/net10.0/Microsoft.Maui.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.22] Discovering: Microsoft.Maui.UnitTests
[xUnit.net 00:00:00.84] Discovered: Microsoft.Maui.UnitTests
[xUnit.net 00:00:00.86] Starting: Microsoft.Maui.UnitTests
Passed HostBuilderThrowsWhenOnlyInterfacesRelatedByInheritanceAreRegistered [124 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: False, retrieveHandlerServiceWithGenerics: True) [10 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: False, retrieveHandlerServiceWithGenerics: False) [< 1 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: True, retrieveHandlerServiceWithGenerics: True) [< 1 ms]
Passed HostBuilderCanRegisterAndResolveCorrespondingHandlerService(registerHandlerServicesWithGenerics: True, retrieveHandlerServiceWithGenerics: False) [< 1 ms]
Passed FactoryBasedHandlerRegistrationReplacesHandler [1 ms]
Passed SecondConfigureMauiHandlersCallReplacesHandler [< 1 ms]
Passed HostBuilderDoesNotResolveHandlersRegisteredUnderMoreDerivedTypes [1 ms]
Passed HostBuilderResolvesToHandlerRegisteredUnderConcreteTypeDespiteAmbiguousInterfacesRegistered [1 ms]
Passed HostBuilderWithoutDefaultsDoesNotRegisterMauiHandlersFactory [1 ms]
Passed HostBuilderCanBuildAHost [< 1 ms]
Passed HostBuilderResolvesHandlerRegisteredUnderBaseInterfaceType(baseInterfaceType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+IMyDerivedViewStub)) [4 ms]
Passed HostBuilderResolvesHandlerRegisteredUnderBaseInterfaceType(baseInterfaceType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+IMyBaseViewStub)) [< 1 ms]
Passed HostBuilderResolvesHandlerRegisteredUnderBaseInterfaceType(baseInterfaceType: typeof(Microsoft.Maui.UnitTests.IViewStub)) [< 1 ms]
Passed HostBuilderResolvesToHandlerRegisteredUnderConcreteTypeOverInterfaceType [1 ms]
Passed HostBuilderResolvesHandlerTypeForServiceRegisteredWithType [< 1 ms]
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.ViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.ViewHandlerStub)) [< 1 ms]
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyDerivedViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyBaseHandlerStub)) [2 ms]
[xUnit.net 00:00:01.19] Finished: Microsoft.Maui.UnitTests
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyBaseViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.Hosting.HostBuilderHandlerTests+MyBaseHandlerStub)) [< 1 ms]
Passed HostBuilderResolvesClosestApplicableServiceType(type: typeof(Microsoft.Maui.UnitTests.IViewStub), expectedHandlerType: typeof(Microsoft.Maui.UnitTests.ViewHandlerStub)) [< 1 ms]
Passed HostBuilderCannotResolveHandlerTypeForServiceRegisteredWithFactory [< 1 ms]
Passed HostBuilderResolvesLastRegisteredHandlerServiceForServiceType [2 ms]
Passed HostBuilderThrowsWhenNoMatchingHandlerServiceTypeIsRegistered [< 1 ms]
Passed HostBuilderResolvesToHandlerRegisteredUnderMostDerivedBaseInterfaceType [2 ms]
Passed HostBuilderWithDefaultsRegistersMauiHandlersFactory [< 1 ms]
Test Run Successful.
Total tests: 25
Passed: 25
Total time: 2.4186 Seconds
⚠️ Failure Details
- ❌ HostBuilderHandlerTests PASSED without fix (should fail) — tests don't catch the bug
- ❌ BlazorWebViewTests (UsePlatformHandlerGenericReplacesDefaultBlazorWebViewHandler, UsePlatformHandlerFactoryReplacesDefaultBlazorWebViewHandler) FAILED with fix (should pass)
📁 Fix files reverted (7 files)
eng/pipelines/ci-copilot.ymlsrc/BlazorWebView/src/Maui/PublicAPI/net-android/PublicAPI.Unshipped.txtsrc/BlazorWebView/src/Maui/PublicAPI/net-ios/PublicAPI.Unshipped.txtsrc/BlazorWebView/src/Maui/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txtsrc/BlazorWebView/src/Maui/PublicAPI/net-tizen/PublicAPI.Unshipped.txtsrc/BlazorWebView/src/Maui/PublicAPI/net-windows/PublicAPI.Unshipped.txtsrc/BlazorWebView/src/Maui/PublicAPI/net/PublicAPI.Unshipped.txt
New files (not reverted):
src/BlazorWebView/src/Maui/MauiBlazorWebViewBuilderExtensions.cs
UI Tests — WebView
Detected UI test categories: WebView
Pre-Flight — Context & Validation
Issue: #34103 - BlazorWebView handler registration needs extensibility for custom platforms - Custom backends must bypass and reimplement AddMauiBlazorWebView() entirely
PR: #34225 - Add UsePlatformHandler for custom BlazorWebView backends
Platforms Affected: Cross-platform BlazorWebView handler registration; testing requested on Android
Files Changed: 7 implementation/API, 2 test
Key Findings
- The linked issue asks for custom platform backends such as Linux/GTK to reuse
AddMauiBlazorWebView()shared services while replacing the platform handler. - The current PR adds
UsePlatformHandler<THandler>()andUsePlatformHandler(Func<IServiceProvider,IViewHandler>), updates PublicAPI across TFMs, and adds direct tests that exercise both overloads with real BlazorWebView types. - Prior review feedback already addressed the constructor activation trap (
new()), DI-friendly factory overload,IViewHandlerconstraint, null checks, and XML documentation about handler-factory service-provider scope and call ordering. - Android gate was previously reported failed/not applicable; this run did not recreate or overwrite
gate/content.md.
Code Review Summary
Verdict: LGTM
Confidence: high
Errors: 0 | Warnings: 1 | Suggestions: 1
Key code review findings:
⚠️ DirectUsePlatformHandlertests validate DI registration only and may be better suited to unit-test feedback loops than device tests.- 💡 Factory overload docs could include an example clarifying that the factory
IServiceProvideris handler-scoped, not the app root provider.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #34225 | Add UsePlatformHandler<THandler>() and factory overload on IMauiBlazorWebViewBuilder to override the default IBlazorWebView handler while preserving AddMauiBlazorWebView() service registrations |
❌ Gate previously failed/not applicable | MauiBlazorWebViewBuilderExtensions.cs, PublicAPI files, BlazorWebView/Core tests |
Current PR is explicit and correct, but still relies on documented call ordering |
Code Review — Deep Analysis
Code Review — PR #34225
Independent Assessment
What this changes: Adds two extension methods (UsePlatformHandler<THandler>() and UsePlatformHandler(Func<IServiceProvider, IViewHandler>)) on IMauiBlazorWebViewBuilder that let a custom platform backend swap the default BlazorWebViewHandler registered by AddMauiBlazorWebView() while preserving all its shared service registrations. Two Core unit tests verify the underlying ConfigureMauiHandlers replacement mechanism; two device tests exercise the new API with real BlazorWebView types end-to-end.
Inferred motivation: Third-party or community platform targets (e.g., Linux/GTK) want to plug a custom BlazorWebView backend into the MAUI BlazorWebView stack without reimplementing all the internal JSInterop / navigation / static-assets service wiring.
Reconciliation with PR Narrative
Author claims: Adds UsePlatformHandler<T>() to let custom backends replace BlazorWebViewHandler while reusing shared services; the mechanism is last-registration-wins; factory overload serves handlers lacking parameterless constructors.
Agreement/disagreement: Agreement. The implementation realizes the stated design. The last-registration-wins claim is grounded in MauiServiceCollection/MauiFactory, and the factory overload documentation correctly calls out the handler-factory service-provider scope.
Findings
⚠️ Warning — New direct tests are device tests even though the covered behavior is DI-only
UsePlatformHandlerGenericReplacesDefaultBlazorWebViewHandler and UsePlatformHandlerFactoryReplacesDefaultBlazorWebViewHandler in BlazorWebViewTests.Services.cs build a MauiApp, resolve IMauiHandlersFactory, and assert handler mappings. They do not render a WebView or create platform views. The tests are functionally correct, but this pure registration behavior would provide faster feedback as unit coverage.
💡 Suggestion — Factory overload docs could include a short IServiceProvider-scope example
The XML docs accurately state that the factory receives the handler factory's provider rather than the app root provider. A short example would make this common footgun more obvious for handlers expecting app-level DI services.
Devil's Advocate
The generic overload's new() constraint is justified because type-based handler activation uses Activator.CreateInstance. The factory overload gives a path for handlers that cannot satisfy that constraint. The ordering caveat is real, but the PR documents it and matches MAUI handler registration semantics.
Verdict: LGTM
Confidence: high
Summary: The PR implementation is correct, trimmer-safe, and complete for its explicit API design. The main concern is test placement/discoverability of the provider-scope caveat, not a correctness blocker.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix-1 | Replace builder extension with primary AddMauiBlazorWebView<THandler>() / factory overloads and make the default handler provisional via TryAddHandler |
Shared registration file, PublicAPI files, BlazorWebView tests | Stronger call-site API, but same public API count and Android run did not complete | |
| 2 | try-fix-2 | Add Core PostConfigureMauiHandlers plus UseBlazorWebViewHandler to make overrides order-independent |
❌ REJECTED before patch/test | None | Too broad; changes Core public API and global handler ordering for a BlazorWebView-specific issue |
| 3 | try-fix-3 | Remove new public API and rely on existing concrete BlazorWebView handler registration overriding the default IBlazorWebView mapping |
Removed extension/PublicAPI entries; retargeted tests to concrete handler override | Smallest diff, but weaker discoverability and not clearly better than PR | |
| PR | PR #34225 | Add explicit UsePlatformHandler<THandler>() and factory overload with docs/tests |
❌ Gate previously failed/not applicable | Production API, PublicAPI, tests | Current fix remains the most discoverable passing design based on available local validation |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-sonnet-4.6 | 1 | Yes | Primary AddMauiBlazorWebView<THandler>() / factory overloads plus TryAddHandler default |
| claude-sonnet-4.6 | 2 | Yes | Core PostConfigureMauiHandlers plus UseBlazorWebViewHandler; rejected as too broad |
| gpt-5.5 | 3 | Yes | Existing concrete handler override convention; applied and partially validated |
Exhausted: Yes
Selected Fix: PR #34225 — No alternative passed all requested Android validation or was demonstrably better. Candidate 1 is plausible but changes API shape; Candidate 2 is too broad; Candidate 3 is smallest but less discoverable and does not provide the explicit affordance requested by the issue.
Report — Final Recommendation
Comparative Report — PR #34225
Candidates Compared
| Rank | Candidate | Result | Assessment |
|---|---|---|---|
| 1 | pr |
Expert review LGTM; Android gate failed | Best available fix. Adds explicit IMauiBlazorWebViewBuilder.UsePlatformHandler APIs that directly address the issue, preserve AddMauiBlazorWebView() shared service registration, support type and factory activation, and document last-registration-wins ordering. |
| 1 | pr-plus-reviewer |
Same as pr |
Expert reviewer had no actionable feedback, so this candidate is identical to pr; it does not improve or regress the raw PR. |
| 3 | try-fix-1 |
Build passed; Android execution blocked | Plausible API alternative using AddMauiBlazorWebView<THandler>() and TryAddHandler, with better override ordering for some call sequences. It is broader than the PR, changes the primary API shape, and was not validated on Android. |
| 4 | try-fix-3 |
Build passed; Android execution blocked | Smallest implementation because it relies on existing concrete handler registration semantics and avoids new API. It is less discoverable and does not provide the explicit BlazorWebView-specific affordance requested by the issue. |
| 5 | try-fix-2 |
Rejected before patch/test | Addresses ordering with a Core-level post-configure concept, but the blast radius is too broad for a BlazorWebView-specific extensibility issue and would require separate API/design review. |
Regression/Test Weighting
The Android gate for the PR failed and must prevent treating the PR as fully validated. However, no candidate in STEP 5a has a passing Android regression result: try-fix-1 and try-fix-3 only reached build/partial validation before Android execution was blocked, and try-fix-2 was not implemented or tested. Because there is no candidate with passing Android regression tests, the final ranking is based on code correctness, API fit, blast radius, and available validation.
Decision
Winner: pr
The raw PR fix is the strongest candidate because it is explicit, surgical, discoverable, and matches existing MAUI handler registration semantics. pr-plus-reviewer is equivalent because the expert reviewer found no actionable changes to apply. The try-fix alternatives either expand API/design scope, reduce discoverability, or lack completed Android validation, so none is demonstrably better than the submitted PR fix.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Adds `IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()` extension method that allows custom platform backends (e.g., Linux/GTK) to replace the default `BlazorWebViewHandler` while reusing all shared service registrations from `AddMauiBlazorWebView()`. ### Problem Custom platform backends cannot use `AddMauiBlazorWebView()` because it hardcodes the built-in `BlazorWebViewHandler`. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.). ### Solution New extension method on `IMauiBlazorWebViewBuilder`: ```csharp builder.Services.AddMauiBlazorWebView() .UsePlatformHandler<GtkBlazorWebViewHandler>(); ``` This keeps all shared services from `AddMauiBlazorWebView()` while allowing the platform-specific handler to be swapped via `ConfigureMauiHandlers` + `AddHandler` (which replaces the prior registration). ### Changes - **New file**: `MauiBlazorWebViewBuilderExtensions.cs` — `UsePlatformHandler<THandler>()` extension method - **PublicAPI updates**: New API entry added to all 6 TFM PublicAPI.Unshipped.txt files - **Unit test**: Validates that a second `ConfigureMauiHandlers` call correctly replaces the handler Fixes #34103 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description
Adds
IMauiBlazorWebViewBuilder.UsePlatformHandler<THandler>()extension method that allows custom platform backends (e.g., Linux/GTK) to replace the defaultBlazorWebViewHandlerwhile reusing all shared service registrations fromAddMauiBlazorWebView().Problem
Custom platform backends cannot use
AddMauiBlazorWebView()because it hardcodes the built-inBlazorWebViewHandler. They must bypass it entirely and duplicate all internal service registrations (JSInterop, navigation, static assets, etc.).Solution
New extension method on
IMauiBlazorWebViewBuilder:This keeps all shared services from
AddMauiBlazorWebView()while allowing the platform-specific handler to be swapped viaConfigureMauiHandlers+AddHandler(which replaces the prior registration).Changes
MauiBlazorWebViewBuilderExtensions.cs—UsePlatformHandler<THandler>()extension methodConfigureMauiHandlerscall correctly replaces the handlerFixes #34103