如何用Appium+Playwright实现.NET MAUI Blazor混合应用UI测试
解决方案
要实现MAUI Blazor混合应用的UI自动化,核心是让Playwright正确连接到BlazorWebView的调试端口,而非默认的全局端口。以下是具体实现步骤:
1. 为MAUI Blazor应用启用WebView2远程调试
在MAUI项目的Platforms/Windows/App.xaml.cs中,添加代码指定WebView2的远程调试端口,避免和系统其他WebView进程冲突:
protected override void OnLaunched(LaunchActivatedEventArgs args) { var builder = MauiProgram.CreateMauiApp().Build(); var window = new MainWindow(); window.Activate(); // 启用BlazorWebView远程调试端口(这里指定为9223) var blazorWebView = window.Content as BlazorWebView; if (blazorWebView != null) { var options = new Microsoft.Web.WebView2.Core.CoreWebView2EnvironmentOptions(); options.AdditionalBrowserArguments = "--remote-debugging-port=9223"; var env = Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(null, null, options).Result; _ = blazorWebView.WebView2.EnsureCoreWebView2Async(env); } base.OnLaunched(args); }
确保项目已安装Microsoft.Web.WebView2 NuGet包。
2. 修正Playwright连接与页面定位逻辑
不要直接取第一个Context和Page,而是遍历页面并等待目标Blazor内容加载完成:
[Test] public async Task SampleTestToCheckHomePage() { // 连接到MAUI BlazorWebView指定的调试端口 var browser = await Playwright.Chromium.ConnectOverCDPAsync("http://localhost:9223"); Page? targetPage = null; // 遍历所有上下文和页面,找到渲染Blazor内容的页面 foreach (var context in browser.Contexts) { foreach (var page in context.Pages) { // 通过页面标题或内容特征判断目标页面 if ((await page.TitleAsync()).Contains("MauiBlazorWeb") || await page.ContentAsync().Contains("Welcome")) { targetPage = page; break; } } if (targetPage != null) break; } Assert.NotNull(targetPage, "未找到BlazorWebView对应的页面实例"); // 等待目标元素加载完成后再断言,避免页面未渲染完成导致的失败 await targetPage.WaitForSelectorAsync("text=Welcome to your new app.", new() { Timeout = 10000 }); var pageContent = await targetPage.ContentAsync(); Assert.That(pageContent.Contains("Welcome to your new app.")); }
3. 优化Appium启动后的等待逻辑
确保Appium启动应用后,等待主窗口和WebView初始化完成,再执行Playwright逻辑:
[OneTimeSetUp] public void RunBeforeAnyTests() { AppiumServerHelper.StartAppiumLocalServer(); var windowsOptions = new AppiumOptions { AutomationName = "windows", PlatformName = "Windows", App = "com.companyname.mauiblazorweb.maui_9zz4h110yvjzm!App", }; driver = new WindowsDriver(windowsOptions); // 设置隐式等待,确保元素加载完成 driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(15); // 等待主窗口出现(可根据实际窗口类名调整) var mainWindow = driver.FindElementByClassName("WindowsForms10.Window.8.app.0.33c0d9d"); Assert.NotNull(mainWindow, "应用主窗口未加载"); }
核心原理
- MAUI Blazor的BlazorWebView基于WebView2控件,必须显式启用远程调试端口,才能让Playwright连接到内部的Web内容。
- 默认的9222端口可能被本地Chrome浏览器或其他WebView进程占用,因此需要指定独立的调试端口。
- WebView2初始化时会创建多个内部页面(如空白启动页),需要通过标题、内容特征筛选出实际渲染Blazor内容的页面。
内容的提问来源于stack exchange,提问作者Bmoe
相关产品推荐
相关产品推荐

