|
| 1 | +--- |
| 2 | +description: 'Playwright .NET test generation instructions' |
| 3 | +applyTo: '**' |
| 4 | +--- |
| 5 | + |
| 6 | +# Playwright .NET Test Generation Instructions |
| 7 | + |
| 8 | +## Test Writing Guidelines |
| 9 | + |
| 10 | +### Code Quality Standards |
| 11 | + |
| 12 | +- **Locators**: Prioritize user-facing, role-based locators (`GetByRole`, `GetByLabel`, `GetByText`, etc.) for resilience and accessibility. Use `await Test.StepAsync()` to group interactions and improve test readability and reporting. |
| 13 | +- **Assertions**: Use auto-retrying web-first assertions. These assertions use `Expect()` from Playwright assertions (e.g., `await Expect(locator).ToHaveTextAsync()`). Avoid checking visibility unless specifically testing for visibility changes. |
| 14 | +- **Timeouts**: Rely on Playwright's built-in auto-waiting mechanisms. Avoid hard-coded waits or increased default timeouts. |
| 15 | +- **Clarity**: Use descriptive test and step titles that clearly state the intent. Add comments only to explain complex logic or non-obvious interactions. |
| 16 | + |
| 17 | +### Test Structure |
| 18 | + |
| 19 | +- **Usings**: Start with `using Microsoft.Playwright;` and either `using Microsoft.Playwright.Xunit;` or `using Microsoft.Playwright.NUnit;` or `using Microsoft.Playwright.MSTest;` for MSTest. |
| 20 | +- **Organization**: Create test classes that inherit from `PageTest` (available in NUnit, xUnit, and MSTest packages) or use `IClassFixture<PlaywrightFixture>` for xUnit with custom fixtures. Group related tests for a feature in the same test class. |
| 21 | +- **Setup**: Use `[SetUp]` (NUnit), `[TestInitialize]` (MSTest), or constructor initialization (xUnit) for setup actions common to all tests (e.g., navigating to a page). |
| 22 | +- **Titles**: Use the appropriate test attribute (`[Test]` for NUnit, `[Fact]` for xUnit, `[TestMethod]` for MSTest) with descriptive method names following C# naming conventions (e.g., `SearchForMovieByTitle`). |
| 23 | + |
| 24 | +### File Organization |
| 25 | + |
| 26 | +- **Location**: Store all test files in a `Tests/` directory or organize by feature. |
| 27 | +- **Naming**: Use the convention `<FeatureOrPage>Tests.cs` (e.g., `LoginTests.cs`, `SearchTests.cs`). |
| 28 | +- **Scope**: Aim for one test class per major application feature or page. |
| 29 | + |
| 30 | +### Assertion Best Practices |
| 31 | + |
| 32 | +- **UI Structure**: Use `ToMatchAriaSnapshotAsync` to verify the accessibility tree structure of a component. This provides a comprehensive and accessible snapshot. |
| 33 | +- **Element Counts**: Use `ToHaveCountAsync` to assert the number of elements found by a locator. |
| 34 | +- **Text Content**: Use `ToHaveTextAsync` for exact text matches and `ToContainTextAsync` for partial matches. |
| 35 | +- **Navigation**: Use `ToHaveURLAsync` to verify the page URL after an action. |
| 36 | + |
| 37 | +## Example Test Structure |
| 38 | + |
| 39 | +```csharp |
| 40 | +using Microsoft.Playwright; |
| 41 | +using Microsoft.Playwright.Xunit; |
| 42 | +using static Microsoft.Playwright.Assertions; |
| 43 | + |
| 44 | +namespace PlaywrightTests; |
| 45 | + |
| 46 | +public class MovieSearchTests : PageTest |
| 47 | +{ |
| 48 | + public override async Task InitializeAsync() |
| 49 | + { |
| 50 | + await base.InitializeAsync(); |
| 51 | + // Navigate to the application before each test |
| 52 | + await Page.GotoAsync("https://debs-obrien.github.io/playwright-movies-app"); |
| 53 | + } |
| 54 | + |
| 55 | + [Fact] |
| 56 | + public async Task SearchForMovieByTitle() |
| 57 | + { |
| 58 | + await Test.StepAsync("Activate and perform search", async () => |
| 59 | + { |
| 60 | + await Page.GetByRole(AriaRole.Search).ClickAsync(); |
| 61 | + var searchInput = Page.GetByRole(AriaRole.Textbox, new() { Name = "Search Input" }); |
| 62 | + await searchInput.FillAsync("Garfield"); |
| 63 | + await searchInput.PressAsync("Enter"); |
| 64 | + }); |
| 65 | + |
| 66 | + await Test.StepAsync("Verify search results", async () => |
| 67 | + { |
| 68 | + // Verify the accessibility tree of the search results |
| 69 | + await Expect(Page.GetByRole(AriaRole.Main)).ToMatchAriaSnapshotAsync(@" |
| 70 | + - main: |
| 71 | + - heading ""Garfield"" [level=1] |
| 72 | + - heading ""search results"" [level=2] |
| 73 | + - list ""movies"": |
| 74 | + - listitem ""movie"": |
| 75 | + - link ""poster of The Garfield Movie The Garfield Movie rating"": |
| 76 | + - /url: /playwright-movies-app/movie?id=tt5779228&page=1 |
| 77 | + - img ""poster of The Garfield Movie"" |
| 78 | + - heading ""The Garfield Movie"" [level=2] |
| 79 | + "); |
| 80 | + }); |
| 81 | + } |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +## Test Execution Strategy |
| 86 | + |
| 87 | +1. **Initial Run**: Execute tests with `dotnet test` or using the test runner in your IDE |
| 88 | +2. **Debug Failures**: Analyze test failures and identify root causes |
| 89 | +3. **Iterate**: Refine locators, assertions, or test logic as needed |
| 90 | +4. **Validate**: Ensure tests pass consistently and cover the intended functionality |
| 91 | +5. **Report**: Provide feedback on test results and any issues discovered |
| 92 | + |
| 93 | +## Quality Checklist |
| 94 | + |
| 95 | +Before finalizing tests, ensure: |
| 96 | + |
| 97 | +- [ ] All locators are accessible and specific and avoid strict mode violations |
| 98 | +- [ ] Tests are grouped logically and follow a clear structure |
| 99 | +- [ ] Assertions are meaningful and reflect user expectations |
| 100 | +- [ ] Tests follow consistent naming conventions |
| 101 | +- [ ] Code is properly formatted and commented |
0 commit comments