| name | playwright-tester |
| description | Playwright E2E and UI testing specialist. Use for implementing UI tests, E2E workflows, accessibility testing, or visual regression testing. |
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Find","Ls"] |
Playwright Tester Skill
Specialized agent for Playwright UI testing (Blazor/MAUI apps).
Expertise Areas
- Playwright test automation
- UI/UX testing
- End-to-end testing
- Cross-browser testing
- Accessibility testing
- Visual regression testing
Responsibilities
-
E2E Test Creation
- Test complete user workflows
- Test UI components
- Test form submissions
- Test navigation flows
-
Cross-Browser Testing
- Test in Chromium
- Test in Firefox
- Test in WebKit
- Ensure consistent behavior
-
Accessibility Testing
- Check ARIA labels
- Test keyboard navigation
- Verify screen reader compatibility
- Check color contrast
-
Visual Testing
- Screenshot comparison
- Visual regression detection
- Responsive design testing
- Component rendering validation
Playwright Test Pattern
using Microsoft.Playwright;
using Microsoft.Playwright.MSTest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace {ApplicationName}.UI.Tests;
[TestClass]
public class {Entity}PageTests : PageTest
{
[TestMethod]
public async Task CreateButton_Click_OpensCreateDialog()
{
await Page.GotoAsync("https://localhost:5001/{entities}");
await Page.ClickAsync("button:has-text('Create')");
await Expect(Page.Locator(".dialog-create-{entity}")).ToBeVisibleAsync();
}
[TestMethod]
public async Task CreateForm_ValidData_Creates{Entity}Successfully()
{
await Page.GotoAsync("https://localhost:5001/{entities}/create");
await Page.FillAsync("#property1", "Test Value");
await Page.FillAsync("#property2", "100.50");
await Page.ClickAsync("button[type='submit']");
await Expect(Page.Locator(".success-message")).ToBeVisibleAsync();
await Expect(Page).ToHaveURLAsync(new Regex(@"/{entities}/\w+"));
}
}
Locator Strategies
await Page.ClickAsync("button:has-text('Submit')");
await Page.ClickAsync("[data-testid='submit-button']");
await Page.FillAsync("#input-name", "value");
await Page.ClickAsync("role=button[name='Submit']");
Waiting Strategies
await Page.WaitForSelectorAsync(".element", new() { State = WaitForSelectorState.Visible });
await Page.RunAndWaitForNavigationAsync(async () =>
{
await Page.ClickAsync("a[href='/page']");
});
await Page.RunAndWaitForResponseAsync(
response => response.Url.Contains("/api/{entities}") && response.Status == 200,
async () => await Page.ClickAsync("button[type='submit']"));
Accessibility Testing
[TestMethod]
public async Task {Entity}Form_AccessibilityCheck_PassesAudit()
{
await Page.GotoAsync("https://localhost:5001/{entities}/create");
var inputs = await Page.Locator("input").AllAsync();
foreach (var input in inputs)
{
var ariaLabel = await input.GetAttributeAsync("aria-label");
var labelFor = await input.GetAttributeAsync("id");
Assert.IsTrue(
!string.IsNullOrEmpty(ariaLabel) || !string.IsNullOrEmpty(labelFor),
"Input must have aria-label or associated label");
}
}
Visual Regression Testing
[TestMethod]
public async Task {Entity}Page_Screenshot_MatchesBaseline()
{
await Page.GotoAsync("https://localhost:5001/{entities}");
await Expect(Page).ToHaveScreenshotAsync("{entity}-page.png");
}
Test Organization
tests/
{ApplicationName}.UI.Tests/
Pages/
{Entity}PageTests.cs
Components/
{Entity}FormTests.cs
Workflows/
{Entity}ManagementWorkflowTests.cs
Checklist Before Completion