Contributing

Thank you for your interest in contributing to the Playwright C# Agentic Framework! This document provides guidelines and instructions for contributing.

Development Setup

Prerequisites

  • .NET SDK 9.0+
  • Git
  • Your preferred IDE (Visual Studio, Rider, VS Code)
  • Playwright browsers

Clone and Setup

git clone https://github.com/kamrankhan54/playwright-csharp-agentic-framework.git cd playwright-csharp-agentic-framework dotnet restore dotnet build

Run Tests

# Run all tests dotnet test ./Tests.E2E/Tests.E2E.csproj # Run specific tests dotnet test --filter "FullyQualifiedName~Login"

Project Structure

Framework/              # Core framework code
  ├── Pages/           # Page Object Model classes
  ├── Support/         # Configuration, base classes
  └── Selectors/        # Selector strategy implementations

Agents/                 # Healing agents
  ├── Planner/         # Test plan generation
  ├── Generator/       # Feature file generation
  └── Healer/          # Selector repair logic

Tests.E2E/             # SpecFlow test project
  ├── Features/        # Gherkin feature files
  ├── Steps/           # Step definitions
  └── Support/         # Hooks, configuration

docs/                   # Documentation
agents/                 # Generated artifacts (registry, plans)
artifacts/              # Test outputs (screenshots, videos)

Code Style

C# Conventions

Follow standard C# coding conventions:

  • Use PascalCase for public members
  • Use camelCase for private fields
  • Use meaningful names
  • Add XML documentation for public APIs

Example:

/// <summary>
/// Represents the login page of the application.
/// </summary>
public class LoginPage : BasePage
{
    private readonly IPage _page;
    
    /// <summary>
    /// Gets the email input field locator.
    /// </summary>
    public ILocator EmailInput => _page.Locator("#user-name");
    
    /// <summary>
    /// Enters the email address into the email field.
    /// </summary>
    /// <param name="email">The email address to enter.</param>
    public async Task EnterEmailAsync(string email)
    {
        await EmailInput.FillAsync(email);
    }
}

Gherkin Style

  • Use clear, business-readable language
  • Keep scenarios focused and independent
  • Use tags for organisation (@smoke, @regression, etc.)

Example:

@smoke @login
Feature: User Authentication
    As a user
    I want to log in to the application
    So that I can access my account

    Scenario: Successful login with valid credentials
        Given I navigate to the login page
        When I enter valid credentials
        Then I should be redirected to the dashboard

Adding New Features

Adding a New Page Object

  1. Create the Page Object class:
// Framework/Pages/NewPage.cs
namespace Framework.Pages;

public class NewPage : BasePage
{
    public NewPage(IPage page, Configuration config) : base(page, config)
    {
    }

    private ILocator MyElement => Page.Locator("#my-element");

    public async Task PerformActionAsync()
    {
        await MyElement.ClickAsync();
    }
}
  1. Register in dependency injection (if using DI container)
  2. Use in step definitions:
[Binding]
public class NewPageSteps
{
    private readonly NewPage _newPage;

    public NewPageSteps(NewPage newPage)
    {
        _newPage = newPage;
    }

    [When(@"I perform action")]
    public async Task WhenIPerformAction()
    {
        await _newPage.PerformActionAsync();
    }
}

Adding a New Selector Strategy

  1. Implement the strategy interface:
// Framework/Selectors/ICustomSelectorStrategy.cs
public interface ICustomSelectorStrategy
{
    string Name { get; }
    ILocator GetLocator(IPage page, string identifier);
    bool IsApplicable(string identifier);
}
  1. Register in the selector registry:
// Framework/Selectors/SelectorRegistry.cs
public void RegisterStrategy(ICustomSelectorStrategy strategy)
{
    _strategies.Add(strategy);
}
  1. Update the Healer to use the new strategy

Writing Tests

Test Organisation

  • Group related scenarios in feature files
  • Use descriptive scenario names
  • Keep scenarios independent (no dependencies between scenarios)

Best Practices

  1. Use Page Objects:
    • Don't use raw selectors in step definitions
    • Encapsulate page interactions in Page Objects
  2. Wait for elements:
    • Use Playwright's built-in waiting
    • Avoid Thread.Sleep()
  3. Clean up:
    • Close pages after scenarios
    • Clear state between tests
  4. Use tags:
    • Tag scenarios for filtering
    • Use @smoke for critical tests
    • Use @skip to temporarily disable tests

Submitting Changes

Pull Request Process

  1. Create a branch:
git checkout -b feature/your-feature-name
  1. Make changes:
    • Write code following style guidelines
    • Add tests for new functionality
    • Update documentation
  2. Run tests:
dotnet test ./Tests.E2E/Tests.E2E.csproj
  1. Commit changes:
git add . git commit -m "Add: Description of changes"
  1. Push and create PR:
git push origin feature/your-feature-name

Commit Messages

Use clear, descriptive commit messages:

Add: New selector strategy for data-test attributes
Fix: Timeout issue in login scenario
Update: Documentation for healing engine
Refactor: Simplify Page Object base class

Pull Request Checklist

  • [ ] Code follows style guidelines
  • [ ] Tests pass locally
  • [ ] Documentation updated
  • [ ] No breaking changes (or documented)
  • [ ] Commit messages are clear

Documentation

Updating Documentation

Documentation is in the docs/ directory. When adding features:

  1. Update relevant documentation files
  2. Add code examples
  3. Include troubleshooting tips if applicable

Documentation Style

  • Use clear, concise language
  • Include code examples
  • Add screenshots for UI-related features
  • Keep examples up-to-date

Testing Contributions

Running Tests

# All tests dotnet test ./Tests.E2E/Tests.E2E.csproj # Specific feature dotnet test --filter "FullyQualifiedName~Login" # With coverage dotnet test /p:CollectCoverage=true

Testing Healing

  1. Run learn to build registry:
dotnet run --project ./Agents/Agents.csproj -- learn \ --test ./Tests.E2E/Tests.E2E.csproj \ --out ./agents/selectors.registry.json
  1. Break a selector intentionally
  2. Run heal:
dotnet run --project ./Agents/Agents.csproj -- heal \ --test ./Tests.E2E/Tests.E2E.csproj
  1. Verify tests pass after healing

Code Review

All contributions go through code review. Reviewers will check:

  • Code quality and style
  • Test coverage
  • Documentation updates
  • Performance implications
  • Breaking changes

Questions?

If you have questions about contributing:

  • Open an issue for discussion
  • Check existing documentation
  • Review similar contributions

Thank you for contributing to the Playwright C# Agentic Framework!