![]() |
VOOZH | about |
dotnet add package GetSkipper.Playwright --version 1.2.0
NuGet\Install-Package GetSkipper.Playwright -Version 1.2.0
<PackageReference Include="GetSkipper.Playwright" Version="1.2.0" />
<PackageVersion Include="GetSkipper.Playwright" Version="1.2.0" />Directory.Packages.props
<PackageReference Include="GetSkipper.Playwright" />Project file
paket add GetSkipper.Playwright --version 1.2.0
#r "nuget: GetSkipper.Playwright, 1.2.0"
#:package GetSkipper.Playwright@1.2.0
#addin nuget:?package=GetSkipper.Playwright&version=1.2.0Install as a Cake Addin
#tool nuget:?package=GetSkipper.Playwright&version=1.2.0Install as a Cake Tool
Test-gating for .NET — skip tests dynamically via a Google Spreadsheet, without touching your test code.
Skipper reads a Google Spreadsheet to decide which tests to skip. Each row has:
| testId | disabledUntil | notes |
|---|---|---|
Tests/Unit/AuthTests.cs > AuthTests > CanLogin |
2026-06-01 |
Flaky on CI |
Tests/E2E/LoginTests.cs > LoginTests > UserCanLogin |
disabledUntil is in the future → test is skipped automaticallydisabledUntil is empty or in the past → test runs normallyNo code changes required in your tests. Configure once, gate everywhere.
| Package | Description | NuGet |
|---|---|---|
| Google Sheets client, resolver, writer | 👁 NuGet |
|
| xUnit v2/v3 integration | 👁 NuGet |
|
| NUnit 3/4 integration | 👁 NuGet |
|
| MSTest v3 integration | 👁 NuGet |
|
| Playwright for .NET | 👁 NuGet |
|
| Reqnroll (SpecFlow) BDD | 👁 NuGet |
// AssemblyInfo.cs — add once to your test project
using GetSkipper.XUnit;
[assembly: TestFramework("GetSkipper.XUnit.SkipperTestFramework", "GetSkipper.XUnit")]
[assembly: SkipperConfig(
SpreadsheetIdEnvVar = "SKIPPER_SPREADSHEET_ID",
CredentialsFile = "service-account.json")]
// Your tests remain unchanged:
public class AuthTests
{
[Fact]
public void CanLogin() { /* ... */ }
}
// AssemblyInfo.cs
using GetSkipper.NUnit;
[assembly: SkipperConfig(
SpreadsheetId = "1abc...",
CredentialsFile = "service-account.json")]
// Your tests remain unchanged:
[TestFixture]
public class AuthTests
{
[Test]
public void CanLogin() { /* ... */ }
}
// SkipperSetup.cs — add once to your test project
using GetSkipper.Core;
using GetSkipper.Core.Credentials;
using GetSkipper.MSTest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public static class SkipperSetup
{
[GlobalTestInitialize]
public static async Task InitAsync()
=> await SkipperGlobalHooks.ConfigureAsync(new SkipperConfig
{
SpreadsheetId = "1abc...",
Credentials = new FileCredentials("service-account.json"),
});
[GlobalTestCleanup]
public static Task CleanupAsync() => SkipperGlobalHooks.AfterAllTestsAsync();
}
// Intercept each test (call from a second [GlobalTestInitialize] or use one method):
public static class SkipperTestGate
{
[GlobalTestInitialize]
public static void BeforeTest(TestContext ctx) => SkipperGlobalHooks.BeforeTest(ctx);
}
using GetSkipper.NUnit;
using GetSkipper.Playwright;
[assembly: SkipperConfig(SpreadsheetId = "1abc...", CredentialsFile = "service-account.json")]
[TestFixture]
public class LoginTests : SkipperPageTest // was: PageTest
{
[Test]
public async Task UserCanLogin()
{
await Page.GotoAsync("/login");
// automatic skip is handled before this line
}
}
// reqnroll.json
{
"bindingAssemblies": [
{ "assembly": "GetSkipper.SpecFlow" }
]
}
SKIPPER_SPREADSHEET_ID=1abc... SKIPPER_CREDENTIALS_FILE=./service-account.json dotnet test
| Column | Required | Description |
|---|---|---|
testId |
Yes | Canonical test identifier |
disabledUntil |
No | ISO-8601 date (2026-06-01). Empty = enabled |
notes |
No | Free text |
| Framework | Format |
|---|---|
| xUnit / NUnit / MSTest | Tests/Unit/AuthTests.cs > AuthTests > CanLogin |
| Playwright | Tests/E2E/LoginTests.cs > LoginTests > UserCanLogin |
| Reqnroll | Features/Auth/Login.feature > User authentication > User can log in |
Reconcile the spreadsheet with your test suite (append new tests, remove deleted ones):
SKIPPER_MODE=sync dotnet test
Typically run on main after all tests pass:
# .github/workflows/ci.yml
- name: Run tests in sync mode
if: github.ref == 'refs/heads/main'
env:
SKIPPER_MODE: sync
SKIPPER_SPREADSHEET_ID: ${{ secrets.SKIPPER_SPREADSHEET_ID }}
GOOGLE_CREDS_B64: ${{ secrets.GOOGLE_CREDS_B64 }}
run: dotnet test
Three ways to supply the Google service account:
// 1. JSON file (local dev)
Credentials = new FileCredentials("./service-account.json")
// 2. Base-64 encoded JSON (CI secrets)
Credentials = new Base64Credentials(Environment.GetEnvironmentVariable("GOOGLE_CREDS_B64")!)
// 3. Inline object
Credentials = new ServiceAccountCredentials(
clientEmail: "skipper@project.iam.gserviceaccount.com",
privateKey: "-----BEGIN RSA PRIVATE KEY-----\n...")
| Variable | Default | Description |
|---|---|---|
SKIPPER_MODE |
read-only |
Set to sync to reconcile spreadsheet |
SKIPPER_SPREADSHEET_ID |
— | Spreadsheet ID (used with SpreadsheetIdEnvVar) |
GOOGLE_CREDS_B64 |
— | Base-64 credentials (used with CredentialsEnvVar) |
SKIPPER_DEBUG |
— | Set to any value for verbose logging |
MIT — see .
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.