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
- 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();
}
}
- Register in dependency injection (if using DI container)
- 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
- Implement the strategy interface:
// Framework/Selectors/ICustomSelectorStrategy.cs
public interface ICustomSelectorStrategy
{
string Name { get; }
ILocator GetLocator(IPage page, string identifier);
bool IsApplicable(string identifier);
}
- Register in the selector registry:
// Framework/Selectors/SelectorRegistry.cs
public void RegisterStrategy(ICustomSelectorStrategy strategy)
{
_strategies.Add(strategy);
}
- 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
- Use Page Objects:
- Don't use raw selectors in step definitions
- Encapsulate page interactions in Page Objects
- Wait for elements:
- Use Playwright's built-in waiting
- Avoid
Thread.Sleep()
- Clean up:
- Close pages after scenarios
- Clear state between tests
- Use tags:
- Tag scenarios for filtering
- Use
@smokefor critical tests - Use
@skipto temporarily disable tests
Submitting Changes
Pull Request Process
- Create a branch:
git checkout -b feature/your-feature-name
- Make changes:
- Write code following style guidelines
- Add tests for new functionality
- Update documentation
- Run tests:
dotnet test ./Tests.E2E/Tests.E2E.csproj
- Commit changes:
git add .
git commit -m "Add: Description of changes"
- 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:
- Update relevant documentation files
- Add code examples
- 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
- Run learn to build registry:
dotnet run --project ./Agents/Agents.csproj -- learn \
--test ./Tests.E2E/Tests.E2E.csproj \
--out ./agents/selectors.registry.json
- Break a selector intentionally
- Run heal:
dotnet run --project ./Agents/Agents.csproj -- heal \
--test ./Tests.E2E/Tests.E2E.csproj
- 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!