playwright

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Playwright Skill

Playwright 技能

E2E testing for Blazor WebAssembly using Playwright .NET with NUnit and .NET Aspire integration. Tests run against the full Aspire application stack with all services.
使用Playwright .NET结合NUnit和.NET Aspire集成,为Blazor WebAssembly进行端到端(E2E)测试。测试会针对包含所有服务的完整Aspire应用栈运行。

Quick Start

快速开始

Basic Page Test

基础页面测试

csharp
[Parallelizable(ParallelScope.Self)]
[TestFixture]
public class BlazorUITests : PageTest
{
    private DistributedApplication? _app;
    private string? _blazorUrl;

    [OneTimeSetUp]
    public async Task OneTimeSetUp()
    {
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.Sorcha_AppHost>();
        _app = await appHost.BuildAsync();
        await _app.StartAsync();
        _blazorUrl = _app.GetEndpoint("blazor-client").ToString();
    }

    [Test]
    public async Task HomePage_LoadsSuccessfully()
    {
        await Page.GotoAsync(_blazorUrl!);
        await Page.WaitForLoadStateAsync();
        await Expect(Page).ToHaveTitleAsync(new Regex("Sorcha|Blueprint"));
    }
}
csharp
[Parallelizable(ParallelScope.Self)]
[TestFixture]
public class BlazorUITests : PageTest
{
    private DistributedApplication? _app;
    private string? _blazorUrl;

    [OneTimeSetUp]
    public async Task OneTimeSetUp()
    {
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.Sorcha_AppHost>();
        _app = await appHost.BuildAsync();
        await _app.StartAsync();
        _blazorUrl = _app.GetEndpoint("blazor-client").ToString();
    }

    [Test]
    public async Task HomePage_LoadsSuccessfully()
    {
        await Page.GotoAsync(_blazorUrl!);
        await Page.WaitForLoadStateAsync();
        await Expect(Page).ToHaveTitleAsync(new Regex("Sorcha|Blueprint"));
    }
}

Locator Patterns

定位器模式

csharp
// Role-based (preferred)
await Page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();

// Text-based
Page.Locator("a:has-text('Designer')")

// MudBlazor components
Page.Locator(".mud-button")
Page.Locator(".mud-table")

// Test IDs (most stable)
Page.Locator("[data-testid='my-element']")
csharp
// Role-based (preferred)
await Page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();

// Text-based
Page.Locator("a:has-text('Designer')")

// MudBlazor components
Page.Locator(".mud-button")
Page.Locator(".mud-table")

// Test IDs (most stable)
Page.Locator("[data-testid='my-element']")

Key Concepts

核心概念

ConceptUsageExample
PageTestBase class providing Page object
class MyTests : PageTest
LocatorLazy element reference
Page.Locator("button")
ExpectAssertion API
await Expect(Page).ToHaveURLAsync(...)
Aspire TestingFull stack integration
DistributedApplicationTestingBuilder
Auto-waitBuilt-in waitingActions wait for actionability
概念用法示例
PageTest提供Page对象的基类
class MyTests : PageTest
Locator延迟加载的元素引用
Page.Locator("button")
Expect断言API
await Expect(Page).ToHaveURLAsync(...)
Aspire Testing全栈集成
DistributedApplicationTestingBuilder
Auto-wait内置等待机制操作会等待元素可交互

Common Patterns

常见模式

JavaScript Error Detection

JavaScript错误检测

csharp
[Test]
public async Task NoJavaScriptErrors()
{
    var errors = new List<string>();
    Page.Console += (_, msg) =>
    {
        if (msg.Type == "error") errors.Add(msg.Text);
    };

    await Page.GotoAsync(_blazorUrl!);
    await Page.WaitForLoadStateAsync();
    
    var criticalErrors = errors.Where(e =>
        !e.Contains("WASM") && !e.Contains("Blazor")).ToList();
    Assert.That(criticalErrors, Is.Empty);
}
csharp
[Test]
public async Task NoJavaScriptErrors()
{
    var errors = new List<string>();
    Page.Console += (_, msg) =>
    {
        if (msg.Type == "error") errors.Add(msg.Text);
    };

    await Page.GotoAsync(_blazorUrl!);
    await Page.WaitForLoadStateAsync();
    
    var criticalErrors = errors.Where(e =>
        !e.Contains("WASM") && !e.Contains("Blazor")).ToList();
    Assert.That(criticalErrors, Is.Empty);
}

Responsive Design Testing

响应式设计测试

csharp
[Test]
public async Task ResponsiveDesign_Works()
{
    await Page.SetViewportSizeAsync(375, 667); // Mobile
    await Page.GotoAsync(_blazorUrl!);
    Assert.That(await Page.TextContentAsync("body"), Is.Not.Empty);

    await Page.SetViewportSizeAsync(1920, 1080); // Desktop
    await Page.ReloadAsync();
    Assert.That(await Page.TextContentAsync("body"), Is.Not.Empty);
}
csharp
[Test]
public async Task ResponsiveDesign_Works()
{
    await Page.SetViewportSizeAsync(375, 667); // Mobile
    await Page.GotoAsync(_blazorUrl!);
    Assert.That(await Page.TextContentAsync("body"), Is.Not.Empty);

    await Page.SetViewportSizeAsync(1920, 1080); // Desktop
    await Page.ReloadAsync();
    Assert.That(await Page.TextContentAsync("body"), Is.Not.Empty);
}

See Also

另请参阅

  • patterns - Locator strategies and assertions
  • workflows - Test setup and CI integration
  • patterns - 定位器策略与断言
  • workflows - 测试设置与CI集成

Related Skills

相关技能

  • See the xunit skill for unit testing patterns
  • See the fluent-assertions skill for SignalR integration tests
  • See the blazor skill for component architecture
  • See the signalr skill for real-time notification testing
  • See the docker skill for container-based test environments
  • 查看xunit技能了解单元测试模式
  • 查看fluent-assertions技能了解SignalR集成测试
  • 查看blazor技能了解组件架构
  • 查看signalr技能了解实时通知测试
  • 查看docker技能了解基于容器的测试环境

Documentation Resources

文档资源

Fetch latest Playwright .NET documentation with Context7.
How to use Context7:
  1. Use
    mcp__context7__resolve-library-id
    to search for "playwright"
  2. Prefer website documentation (
    /websites/playwright_dev_dotnet
    ) over source code
  3. Query with
    mcp__context7__query-docs
    using the resolved library ID
Library ID:
/websites/playwright_dev_dotnet
Recommended Queries:
  • "Locators selectors best practices"
  • "NUnit test fixtures setup teardown"
  • "Wait for element network idle auto-waiting"
  • "Assertions expect API"
  • "Trace viewer debugging"
使用Context7获取最新的Playwright .NET文档。
Context7使用方法:
  1. 使用
    mcp__context7__resolve-library-id
    搜索"playwright"
  2. 优先选择网站文档 (
    /websites/playwright_dev_dotnet
    )而非源代码
  3. 使用解析后的库ID,通过
    mcp__context7__query-docs
    进行查询
库ID:
/websites/playwright_dev_dotnet
推荐查询:
  • "Locators selectors best practices"
  • "NUnit test fixtures setup teardown"
  • "Wait for element network idle auto-waiting"
  • "Assertions expect API"
  • "Trace viewer debugging"