Testing modern web applications goes beyond unit and integration testing. While those tests verify business logic and APIs, they don't confirm whether the entire application works correctly from a user's perspective. That's where end-to-end (E2E) testing becomes essential.
Playwright, developed by Microsoft, is a modern browser automation framework that enables developers to test web applications across Chromium, Firefox, and WebKit using a single API. It provides reliable, fast, and feature-rich testing for ASP.NET Core applications.
In this article, you'll learn how to set up Playwright, write effective end-to-end tests, and follow best practices for building reliable test automation.
Why Choose Playwright?
Traditional browser automation tools often struggle with flaky tests, inconsistent browser behavior, and limited debugging capabilities. Playwright addresses these challenges by providing built-in auto-waiting, cross-browser support, and powerful debugging features.
Key benefits include:
Cross-browser testing
Automatic waiting for elements
Parallel test execution
Network request interception
Screenshots and video recording
Easy CI/CD integration
These features make Playwright a strong choice for testing ASP.NET Core web applications.
Installing Playwright
Create a Playwright test project using the .NET CLI:
dotnet new playwright
Install the required browsers:
pwsh bin/Debug/net8.0/playwright.ps1 install
This downloads Chromium, Firefox, and WebKit, allowing the same tests to run across multiple browsers.
Writing Your First Test
The following example verifies that the application's home page loads successfully.
using Microsoft.Playwright;
using Microsoft.Playwright.NUnit;
public class HomePageTests : PageTest
{
[Test]
public async Task HomePage_Should_Load()
{
await Page.GotoAsync("https://localhost:5001");
await Expect(Page).ToHaveTitleAsync(
new Regex("Home"));
}
}
The test launches a browser, navigates to the application, and verifies the page title.
Interacting with Page Elements
Playwright provides multiple locator strategies for interacting with UI elements.
Example:
await Page.GetByLabel("Email")
.FillAsync("[email protected]");
await Page.GetByLabel("Password")
.FillAsync("Password123");
await Page.GetByRole(AriaRole.Button,
new() { Name = "Login" })
.ClickAsync();
Using semantic locators such as labels and roles makes tests more readable and resilient than relying on CSS selectors.
Verifying Application Behavior
Playwright supports rich assertions for validating application behavior.
await Expect(Page.GetByText("Welcome"))
.ToBeVisibleAsync();
You can verify:
Page titles
URLs
Text content
Form validation
Button states
Element visibility
These assertions help ensure the application behaves as expected from the user's perspective.
Mocking External APIs
Applications often depend on external APIs that may be unavailable or return unpredictable responses during testing.
Playwright allows requests to be intercepted and mocked.
await Page.RouteAsync(
"**/api/products",
async route =>
{
await route.FulfillAsync(new()
{
Body = """
[
{ "id": 1, "name": "Laptop" }
]
"""
});
});
Mocking external services keeps tests deterministic and independent of third-party systems.
Debugging Failed Tests
Playwright provides several debugging features that simplify failure analysis.
Useful options include:
Screenshots
Video recordings
Trace Viewer
Console logs
For example:
await Page.ScreenshotAsync(new()
{
Path = "failure.png"
});
Capturing screenshots during failures makes diagnosing UI issues significantly easier.
Running Tests in CI/CD
Playwright integrates well with GitHub Actions, Azure DevOps, and other CI/CD platforms.
A typical pipeline includes:
Build the application.
Start the ASP.NET Core application.
Install Playwright browsers.
Execute Playwright tests.
Publish test reports and screenshots.
Running end-to-end tests automatically helps detect regressions before deployment.
Best Practices
Keep end-to-end tests focused on critical user workflows.
Use semantic locators instead of fragile CSS selectors.
Mock external services when appropriate.
Run tests in parallel to reduce execution time.
Capture screenshots and traces for failed tests.
Execute Playwright tests as part of your CI/CD pipeline.
Combine Playwright with unit and integration tests for comprehensive test coverage.
Common Mistakes
Testing Every Scenario with Playwright
End-to-end tests are slower than unit or integration tests. Reserve Playwright for validating complete user workflows, while keeping business logic covered by faster tests.
Using Fragile Selectors
Selectors based on HTML structure or CSS classes are more likely to break after UI changes. Prefer accessible locators such as labels, roles, and test IDs.
Ignoring Test Isolation
Tests should be independent of one another. Shared state between tests can lead to inconsistent and difficult-to-reproduce failures.
Depending on External Services
Tests that rely on live third-party APIs may fail because of network issues rather than application defects. Mock external dependencies whenever possible.
Conclusion
Playwright has become one of the most powerful tools for end-to-end testing of ASP.NET Core applications. Its cross-browser support, automatic waiting, reliable locators, and advanced debugging capabilities help teams build stable and maintainable test suites.
While Playwright is excellent for validating complete user journeys, it should complement—not replace—unit and integration testing. A balanced testing strategy ensures that business logic is verified quickly while critical application workflows are validated through browser automation.
By adopting Playwright, following reliable testing practices, and integrating automated tests into your CI/CD pipeline, you can improve software quality, detect regressions early, and deliver more reliable ASP.NET Core applications with confidence.