OldRepublic.PlaywrightBase 1.0.8

dotnet add package OldRepublic.PlaywrightBase --version 1.0.8
                    
NuGet\Install-Package OldRepublic.PlaywrightBase -Version 1.0.8
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OldRepublic.PlaywrightBase" Version="1.0.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OldRepublic.PlaywrightBase" Version="1.0.8" />
                    
Directory.Packages.props
<PackageReference Include="OldRepublic.PlaywrightBase" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OldRepublic.PlaywrightBase --version 1.0.8
                    
#r "nuget: OldRepublic.PlaywrightBase, 1.0.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OldRepublic.PlaywrightBase@1.0.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OldRepublic.PlaywrightBase&version=1.0.8
                    
Install as a Cake Addin
#tool nuget:?package=OldRepublic.PlaywrightBase&version=1.0.8
                    
Install as a Cake Tool

OldRepublic.PlaywrightBase

Reusable Playwright automation framework for NUnit-based UI/API tests.

Installation

dotnet add package OldRepublic.PlaywrightBase

Notes

  • Targets .NET 8.
  • Includes base test/page patterns and Playwright driver abstractions.
  • Depends on Microsoft.Playwright; install browsers in consuming projects when needed.

Current Framework Stack

  • .NET 8.0 - Target framework
  • NUnit 3.14.0 - Testing framework
  • Microsoft.Playwright 1.48.0 - Browser automation
  • Allure.NUnit 2.12.1 - Test reporting
  • FluentAssertions 6.12.0 - Assertion library

Project Architecture

Core Components

  1. PlaywrightFramework - Core framework library containing:

    • Base classes (BaseTest, BasePage)
    • Driver management (PlaywrightDriver, PlaywrightDriverInitializer)
    • Configuration services
    • Extensions and utilities
  2. QaEsign - Test project containing:

    • Test fixtures and test classes
    • Page objects specific to the application
    • Test data and models
    • Configuration files

NUnit Setup Structure

// Assembly-level attributes in EsignFixture.cs
[assembly: Parallelizable(ParallelScope.Fixtures)]
[assembly: LevelOfParallelism(4)]

[SetUpFixture]
public class EsignFixture : PlaywrightFixture
{
    [OneTimeSetUp]
    public static void GlobalSetup()
    {
        // Initialize Playwright and configuration
    }

    [OneTimeTearDown]
    public static void GlobalTeardown()
    {
        // Clean up resources
    }
}

Test Class Structure

Basic Test Class Template

[TestFixture]
[AllureNUnit]
[AllureEpic("UI Tests")]
[AllureFeature("Login functionality")]
public class MyTests : BaseTest
{
    private IBrowser _browser;
    private IBrowserContext _browserContext;
    private IPage _page;

    [SetUp]
    public async Task SetUp()
    {
        _browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
        {
            Headless = Settings.Headless
        });
        _browserContext = await _browser.NewContextAsync();
        _page = await _browserContext.NewPageAsync();
    }

    [Test]
    [AllureStory("User login")]
    public async Task Login_WithValidCredentials_ShouldSucceed()
    {
        // Test implementation
    }

    [TearDown]
    public async Task TearDown()
    {
        await _page?.CloseAsync();
        await _browserContext?.CloseAsync();
        await _browser?.CloseAsync();
    }
}

Parallel Execution Configuration

Current Configuration

The project is configured for parallel execution at the fixture level:

[assembly: Parallelizable(ParallelScope.Fixtures)]
[assembly: LevelOfParallelism(4)]

This means:

  • Different test fixtures can run in parallel
  • Up to 4 worker threads are used
  • Tests within the same fixture run sequentially

Thread Safety

Tests are made thread-safe by:

  1. Each test gets its own browser instance
  2. Separate browser contexts per test
  3. No shared mutable state between tests

Test Categories and Organization

Using NUnit Categories

[Test]
[Category("Smoke")]
[Category("Critical")]
public async Task ImportantFeature_ShouldWork()
{
    // Test implementation
}

Running Specific Categories

# Run only smoke tests
dotnet test --filter "TestCategory=Smoke"

# Run multiple categories
dotnet test --filter "TestCategory=Smoke|TestCategory=Critical"

# Exclude categories
dotnet test --filter "TestCategory!=Slow"

Data-Driven Testing

TestCase Attribute

[TestCase("user1@test.com", "password1")]
[TestCase("user2@test.com", "password2")]
public async Task Login_WithDifferentUsers_ShouldWork(string email, string password)
{
    // Test implementation using parameters
}

TestCaseSource

public class LoginTestData
{
    public static IEnumerable<TestCaseData> ValidCredentials()
    {
        yield return new TestCaseData("user1@test.com", "password1")
            .SetName("StandardUser");
        yield return new TestCaseData("admin@test.com", "adminpass")
            .SetName("AdminUser");
    }
}

[Test]
[TestCaseSource(typeof(LoginTestData), nameof(LoginTestData.ValidCredentials))]
public async Task Login_WithValidCredentials_ShouldSucceed(string email, string password)
{
    // Test implementation
}

Allure Integration

Test Annotations

[TestFixture]
[AllureNUnit]
[AllureEpic("E-Signature System")]
[AllureFeature("Document Signing")]
public class DocumentSigningTests : BaseTest
{
    [Test]
    [AllureStory("Sign single document")]
    [AllureSeverity(SeverityLevel.Critical)]
    [AllureDescription("Verify that a user can sign a single document successfully")]
    public async Task SignDocument_SingleDocument_ShouldSucceed()
    {
        // Test implementation
    }
}

Step Annotations in Page Objects

[AllureStep("Login with username: {username}")]
public async Task LoginAsync(string username, string password)
{
    await _page.FillAsync("#username", username);
    await _page.FillAsync("#password", password);
    await _page.ClickAsync("#login-button");
}

Configuration Management

appsettings.json Structure

{
    "TestEnv": "DEV",
    "Browser": "chrome",
    "Headless": false,
    "Timeout": 3000,
    "BrowserWindowSize": {
        "Width": 1500,
        "Height": 720
    },
    "ScreenshotPath": "Reports\\Screenshots",
    "Environments": {
        "DEV": {
            "BaseUrl": "https://smkt.dev.oldrepublictitle.com",
            "ESignUrl": "https://smkt.dev.oldrepublictitle.com/esign/v1",
            "Authentication": {
                "GrantType": "password",
                "ClientId": "sm-portal",
                "AuthUrl": "https://smkt.dev.oldrepublictitle.com/auth/realms/supermarket/protocol/openid-connect/token"
            }
        }
    }
}

Environment Override

# Set environment via environment variable
$env:TestEnv = "QA"
dotnet test

# Or use command line parameter (if implemented)
dotnet test -- TestEnv=QA

Avoid storing test credentials in passwords.json. The framework now reads environment variables and they override JSON values.

PowerShell examples (for DEV environment):

  • Current process (session-only):
$env:Environments__DEV__Authentication__Passwords__Super = "<SUPER_PASSWORD>"
$env:Environments__DEV__Authentication__Passwords__Admin = "<ADMIN_PASSWORD>"
$env:Environments__DEV__Authentication__Passwords__User = "<USER_PASSWORD>"
  • Persistent user-scoped environment variables:
[System.Environment]::SetEnvironmentVariable("Environments__DEV__Authentication__Passwords__Super","SUPER_PASSWORD","User")
[System.Environment]::SetEnvironmentVariable("Environments__DEV__Authentication__Passwords__Admin","ADMIN_PASSWORD","User")
[System.Environment]::SetEnvironmentVariable("Environments__DEV__Authentication__Passwords__User","USER_PASSWORD","User")

Run tests in the same shell session:

dotnet test QaEsign

Notes:

  • Use double underscore (__) for nested keys.
  • Replace DEV in the variable name with your active TestEnv (for example, QA or UAT).
  • passwords.json is optional; if both are present, environment variables win.

Running Tests

Basic Commands

# Run all tests
dotnet test QaEsign

# Run with specific verbosity
dotnet test QaEsign --logger "console;verbosity=detailed"

# Run specific test class
dotnet test QaEsign --filter "FullyQualifiedName~ESignTests"

# Run specific test method
dotnet test QaEsign --filter "FullyQualifiedName~NavigateToESignUrl_ShouldLoadPage"

Running Tests in Parallel

# Run with maximum parallelism
dotnet test QaEsign --parallel

# Control parallelization
dotnet test QaEsign -- NUnit.NumberOfTestWorkers=2

Debugging and Troubleshooting

Running in Debug Mode

  1. Set "Headless": false in appsettings.json
  2. Add breakpoints in your tests
  3. Run specific test in debug mode

Common Issues

  1. Browser not launching: Check Playwright installation
  2. Tests timing out: Increase timeout values in configuration
  3. Parallel test failures: Check for shared state or resource conflicts
  4. Allure reports not generating: Verify allureConfig.json path

Test Artifacts

  • Screenshots: Automatically captured on test failures
  • Logs: Structured logging with Serilog
  • Allure Reports: Comprehensive test execution reports
  • Videos: Can be enabled in Playwright configuration

Best Practices

  1. Use meaningful test names that describe the scenario and expected outcome
  2. Implement proper setup and teardown to ensure test isolation
  3. Use Page Object Model to separate test logic from UI interactions
  4. Add appropriate Allure annotations for better reporting
  5. Handle async operations properly with await/async patterns
  6. Use FluentAssertions for readable and descriptive assertions
  7. Organize tests with categories for selective execution
  8. Keep test data separate from test logic

Example Complete Test

[TestFixture]
[AllureNUnit]
[AllureEpic("E-Signature System")]
[AllureFeature("User Authentication")]
public class LoginTests : BaseTest
{
    private ORTLoginPage _loginPage;
    private IBrowser _browser;
    private IBrowserContext _browserContext;
    private IPage _page;

    [SetUp]
    public async Task SetUp()
    {
        _browser = await Playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
        {
            Headless = Settings.Headless
        });
        _browserContext = await _browser.NewContextAsync();
        _page = await _browserContext.NewPageAsync();
        _loginPage = new ORTLoginPage(_page, Logger);
    }

    [Test]
    [AllureStory("Valid user login")]
    [AllureSeverity(SeverityLevel.Critical)]
    [Category("Smoke")]
    [Category("Authentication")]
    public async Task Login_WithValidCredentials_ShouldNavigateToHomePage()
    {
        // Arrange
        var username = EnvConfig.Value.Authentication.Usernames.User;
        var password = "validPassword";

        // Act
        await _page.GotoAsync(EnvConfig.Value.BaseUrl);
        var loginResult = await _loginPage.LoginAsync(username, password);

        // Assert
        loginResult.Should().BeTrue("Login should succeed with valid credentials");
        
        var currentUrl = _page.Url;
        currentUrl.Should().NotContain("login", "User should be redirected away from login page");
    }

    [TearDown]
    public async Task TearDown()
    {
        if (_page != null)
        {
            await TakeScreenshotAsync(_page, TestContext.CurrentContext.Test.Name);
        }
        
        await _page?.CloseAsync();
        await _browserContext?.CloseAsync();
        await _browser?.CloseAsync();
    }
}

NuGet Release Commands

Local package testing

  1. Pack to a local feed folder:
dotnet pack ".\PlaywrightFramework\PlaywrightFramework.csproj" -c Release -o ".\artifacts\local-feed" /p:Version=1.0.5-local.1
  1. Add the local feed as a NuGet source (one-time setup):
dotnet nuget add source "C:\Users\<User>\<Project Root>\qa-playwright\artifacts\local-feed" --name LocalPlaywright
  1. Install in a consumer project:
dotnet add ".\QaEsign\QaEsign.csproj" package OldRepublic.PlaywrightBase --version 1.0.5-local.1 --source "C:\Users\<User>\<Project Root>\qa-playwright\artifacts\local-feed"
  1. If updates do not appear, either bump the local version (-local.2, -local.3, etc.) or clear cache:
dotnet nuget locals global-packages --clear

Publish to NuGet.org

  1. Pack with a new version (NuGet.org does not allow overwrite):
dotnet pack ".\PlaywrightFramework\PlaywrightFramework.csproj" -c Release -o ".\artifacts\nuget" /p:Version=1.0.*
  1. Push to NuGet.org:
dotnet nuget push ".\artifacts\nuget\OldRepublic.PlaywrightBase.1.0.6.nupkg" --api-key "<YOUR_NUGET_API_KEY>" --source "https://api.nuget.org/v3/index.json" --skip-duplicate
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.8 94 3/17/2026
1.0.7 90 3/16/2026
1.0.6 91 3/4/2026
1.0.5 87 3/3/2026
1.0.4 95 3/3/2026
1.0.2 85 3/3/2026
1.0.0 91 3/3/2026