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" />
<PackageReference Include="OldRepublic.PlaywrightBase" />
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
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#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
#tool nuget:?package=OldRepublic.PlaywrightBase&version=1.0.8
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
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
PlaywrightFramework - Core framework library containing:
- Base classes (
BaseTest,BasePage) - Driver management (
PlaywrightDriver,PlaywrightDriverInitializer) - Configuration services
- Extensions and utilities
- Base classes (
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:
- Each test gets its own browser instance
- Separate browser contexts per test
- 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
Passwords via Environment Variables (recommended)
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
DEVin the variable name with your activeTestEnv(for example,QAorUAT). passwords.jsonis 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
- Set
"Headless": falsein appsettings.json - Add breakpoints in your tests
- Run specific test in debug mode
Common Issues
- Browser not launching: Check Playwright installation
- Tests timing out: Increase timeout values in configuration
- Parallel test failures: Check for shared state or resource conflicts
- 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
- Use meaningful test names that describe the scenario and expected outcome
- Implement proper setup and teardown to ensure test isolation
- Use Page Object Model to separate test logic from UI interactions
- Add appropriate Allure annotations for better reporting
- Handle async operations properly with await/async patterns
- Use FluentAssertions for readable and descriptive assertions
- Organize tests with categories for selective execution
- 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
- Pack to a local feed folder:
dotnet pack ".\PlaywrightFramework\PlaywrightFramework.csproj" -c Release -o ".\artifacts\local-feed" /p:Version=1.0.5-local.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
- 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"
- 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
- 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.*
- 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 | Versions 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.
-
net10.0
- Allure.Commons (>= 3.5.0.73)
- Allure.NUnit (>= 2.12.1)
- Microsoft.Extensions.Configuration (>= 9.0.0)
- Microsoft.Extensions.Configuration.EnvironmentVariables (>= 9.0.0)
- Microsoft.Extensions.Configuration.Json (>= 9.0.0)
- Microsoft.Extensions.Logging (>= 9.0.0)
- Microsoft.Extensions.Logging.Console (>= 9.0.0)
- Microsoft.Playwright (>= 1.48.0)
- Newtonsoft.Json (>= 13.0.3)
- NUnit (>= 3.14.0)
- NUnit3TestAdapter (>= 4.5.0)
- Serilog (>= 4.2.0)
- Serilog.Extensions.Logging (>= 8.0.0)
- Serilog.Settings.Configuration (>= 8.0.4)
- Serilog.Sinks.Console (>= 6.0.0)
- Serilog.Sinks.File (>= 6.0.0)
-
net8.0
- Allure.Commons (>= 3.5.0.73)
- Allure.NUnit (>= 2.12.1)
- Microsoft.Extensions.Configuration (>= 9.0.0)
- Microsoft.Extensions.Configuration.EnvironmentVariables (>= 9.0.0)
- Microsoft.Extensions.Configuration.Json (>= 9.0.0)
- Microsoft.Extensions.Logging (>= 9.0.0)
- Microsoft.Extensions.Logging.Console (>= 9.0.0)
- Microsoft.Playwright (>= 1.48.0)
- Newtonsoft.Json (>= 13.0.3)
- NUnit (>= 3.14.0)
- NUnit3TestAdapter (>= 4.5.0)
- Serilog (>= 4.2.0)
- Serilog.Extensions.Logging (>= 8.0.0)
- Serilog.Settings.Configuration (>= 8.0.4)
- Serilog.Sinks.Console (>= 6.0.0)
- Serilog.Sinks.File (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.