Playwright C# Test Automation Project Structure
Here’s a detailed project structure for a UI and API testing framework using C#, Playwright, and the Page Object Model (POM), incorporating the additional tools and files like Utilities
, GitHub workflows, and templates.
Project Structure
PlaywrightTestingFramework/
│
├── .github/
│ ├── CODEOWNERS
│ ├── workflows/
│ │ └── nightly-build.yml
│ └── PULL_REQUEST_TEMPLATE.md
│
├── src/
│ ├── Pages/
│ │ ├── BasePage.cs
│ │ ├── HomePage.cs
│ │ ├── LoginPage.cs
│ │ └── APIPage.cs
│ │
│ ├── Utilities/
│ │ ├── CommonHelpers.cs
│ │ ├── ConfigReader.cs
│ │ └── Logger.cs
│ │
│ ├── Tests/
│ │ ├── UI/
│ │ │ ├── LoginTests.cs
│ │ │ └── HomeTests.cs
│ │ ├── API/
│ │ └── APITests.cs
│ │
│ ├── Drivers/
│ │ └── BrowserFactory.cs
│ │
│ ├── Config/
│ │ └── appsettings.json
│ │
│ └── Program.cs
│
├── .gitignore
├── README.md
├── PlaywrightTestingFramework.sln
└── PlaywrightTestingFramework.csproj
Key Files and Examples
1. .github/CODEOWNERS
# Assign code reviewers/owners
* @team-lead @qa-engineer
2. .github/PULL_REQUEST_TEMPLATE.md
# Pull Request Template
## Description
Describe the changes made in this PR.
## Checklist
- [ ] Code compiles successfully.
- [ ] All tests pass.
- [ ] Code is properly documented.
## Linked Issues
Closes #[issue-number].
3. .github/workflows/nightly-build.yml
name: Nightly Build
on:
schedule:
- cron: '0 0 * * *'
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.0'
- name: Install dependencies
run: dotnet restore
- name: Run tests
run: dotnet test --logger:trx
4. Utilities Files
CommonHelpers.cs
public static class CommonHelpers
{
public static string GenerateRandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return new string(Enumerable.Repeat(chars, length).Select(s => s[new Random().Next(s.Length)]).ToArray());
}
}
ConfigReader.cs
public static class ConfigReader
{
public static string GetConfigValue(string key)
{
return File.ReadAllText("Config/appsettings.json")[key];
}
}
5. Page Object Files
BasePage.cs
public class BasePage
{
protected readonly IPage page;
public BasePage(IPage page)
{
this.page = page;
}
}
LoginPage.cs
public class LoginPage : BasePage
{
private string usernameInput = "#username";
private string passwordInput = "#password";
private string loginButton = "#login";
public LoginPage(IPage page) : base(page) { }
public async Task Login(string username, string password)
{
await page.FillAsync(usernameInput, username);
await page.FillAsync(passwordInput, password);
await page.ClickAsync(loginButton);
}
}
6. Driver Setup
BrowserFactory.cs
public class BrowserFactory
{
public static async Task<IPage> LaunchBrowser(string browserName)
{
var playwright = await Playwright.CreateAsync();
IBrowser browser = browserName.ToLower() switch
{
"chrome" => await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = true }),
"firefox" => await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions { Headless = true }),
"edge" => await playwright.Chromium.LaunchPersistentContextAsync("user-data-dir"),
"safari" => await playwright.Webkit.LaunchAsync(new BrowserTypeLaunchOptions { Headless = true }),
_ => throw new ArgumentException("Unsupported browser type"),
};
return await browser.NewPageAsync();
}
}
7. Tests
LoginTests.cs
[TestClass]
public class LoginTests
{
private IPage page;
[TestInitialize]
public async Task Setup()
{
page = await BrowserFactory.LaunchBrowser("chrome");
}
[TestMethod]
public async Task LoginWithValidCredentials()
{
var loginPage = new LoginPage(page);
await loginPage.Login("testuser", "password");
Assert.IsTrue(await page.IsVisibleAsync("#welcomeMessage"));
}
[TestCleanup]
public async Task Teardown()
{
await page.CloseAsync();
}
}
APITests.cs
[TestClass]
public class APITests
{
private HttpClient httpClient;
[TestInitialize]
public void Setup()
{
httpClient = new HttpClient();
}
[TestMethod]
public async Task GetRequestTest()
{
var response = await httpClient.GetAsync("https://api.example.com/data");
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
}
8. appsettings.json
{
"BaseUrl": "https://example.com",
"Username": "testuser",
"Password": "password"
}
9. README.md
# Playwright Testing Framework
## Overview
This is a C# testing framework using Playwright for both UI and API testing, designed with the Page Object Model for reusability and maintainability.
## Features
- Cross-browser testing (Chrome, Firefox, Edge, Safari).
- API and UI testing in one framework.
- GitHub Actions for CI/CD.
## Setup
1. Clone the repository.
2. Install dependencies: `dotnet restore`.
3. Run tests: `dotnet test`.
## Folder Structure
- `Pages`: Contains POM files for UI testing.
- `Utilities`: Common helper functions.
- `Tests`: Contains test scripts for UI and API.
This project structure is modular, reusable, and integrates CI/CD, ensuring best practices for test automation!