Skip to content

get-skipper/skipper

Repository files navigation

Skipper

Enable and disable tests directly from a Google Spreadsheet — no code changes required.

Skipper integrates with your existing test suite via a minimal config. Each test is identified by its file path + title. Set a disabledUntil date in the spreadsheet to skip a test until that date; leave it empty (or set a past date) to run it normally.

Packages

Package Framework
@get-skipper/playwright Playwright
@get-skipper/jest Jest
@get-skipper/vitest Vitest
@get-skipper/cypress Cypress
@get-skipper/nightwatch Nightwatch.js

How It Works

  • read-only mode (default): Skipper reads the spreadsheet at the start of the test run and skips any test whose disabledUntil date is in the future.
  • sync mode (SKIPPER_MODE=sync): Same as read-only, plus after the run Skipper reconciles the spreadsheet — adding rows for new tests and, when SKIPPER_SYNC_ALLOW_DELETE=true, removing rows for tests no longer in the suite.

Spreadsheet Schema

Create a Google Spreadsheet with the following columns in the first row (header):

testId disabledUntil notes
tests/auth/login.spec.ts > login > should log in
tests/checkout/payment.spec.ts > payment > stripe 2026-04-01 Flaky until fix
tests/payments/refund.spec.ts > refund 2099-12-31 Disabled indefinitely
  • testId{relative file path} > {describe blocks} > {test name}, automatically generated by the plugin.
  • disabledUntil — ISO 8601 date (e.g. 2026-04-01). Empty or past date = test runs. Future date = test is skipped.
  • notes — optional free-text field, ignored by the plugin.

Configuration Reference

All Skipper plugins accept the same SkipperConfig object:

Option Type Required Default Description
spreadsheetId string The Google Spreadsheet ID (from the URL)
credentials object Service account credentials — see below
sheetName string first tab Name of the sheet tab to read/write
referenceSheets string[] [] Additional sheet tabs to read (read-only); merged with the primary sheet
testIdColumn string "testId" Column header for the test identifier
disabledUntilColumn string "disabledUntil" Column header for the disable date

Credentials

// Base64-encoded JSON (recommended for CI)
credentials: { credentialsBase64: process.env.GOOGLE_CREDS_B64! }

// Path to a local JSON file (recommended for local dev)
credentials: { credentialsFile: './service-account.json' }

// Raw service account object
credentials: { client_email: '...', private_key: '...' }

sheetName

By default Skipper uses the first tab of the spreadsheet. Use sheetName to target a specific tab:

{
  spreadsheetId: '...',
  credentials: { credentialsBase64: '...' },
  sheetName: 'E2E Tests', // reads and writes to this tab only
}

referenceSheets

Additional sheet tabs to read (never written to). Useful for sharing a common list of disabled tests across multiple suites. When the same testId appears in more than one sheet, the most restrictive (latest future) disabledUntil wins:

{
  spreadsheetId: '...',
  credentials: { credentialsBase64: '...' },
  sheetName: 'E2E Tests',        // primary sheet (read + write in sync mode)
  referenceSheets: ['Shared'],   // additional sheets (read-only)
}

Google Sheets Setup

1. Create a Google Cloud Project and enable the API

  1. Go to Google Cloud Console
  2. Create a new project (or select an existing one)
  3. Navigate to APIs & Services → Library
  4. Search for Google Sheets API and enable it

2. Create a Service Account

  1. Navigate to APIs & Services → Credentials
  2. Click Create Credentials → Service Account
  3. Give it a name (e.g. skipper-bot) and click Done
  4. Click on the service account → Keys tab → Add Key → Create new key → JSON
  5. Download the JSON file — keep it secret

3. Share the Spreadsheet

Open your Google Spreadsheet and share it with the service account email (found in the JSON file as client_email):

  • Viewer role for read-only mode
  • Editor role for sync mode

4. Prepare Credentials for CI

Convert the JSON file to a base64 string for use as a CI secret:

base64 -i service-account.json | tr -d '\n'

Save the output as a secret named GOOGLE_CREDS_B64 in your CI environment (e.g. GitHub Actions secrets).

For local development, keep the JSON file and reference it via credentialsFile:

credentials: { credentialsFile: './service-account.json' }

5. Populate the Spreadsheet for the First Time

Run your test suite in sync mode once to auto-populate all test rows:

SKIPPER_MODE=sync SKIPPER_SPREADSHEET_ID=<your-spreadsheet-id> pnpm test

All tests will be added to the spreadsheet with an empty disabledUntil (enabled by default). You can then set dates in the spreadsheet to disable specific tests.

Environment Variables

Variable Default Description
SKIPPER_MODE read-only Set to sync to enable spreadsheet reconciliation after the test run
SKIPPER_FAIL_OPEN true When true, runs all tests if the API is unreachable and no valid cache exists. Set to false to crash instead
SKIPPER_CACHE_TTL 300 Seconds a local .skipper-cache.json is considered valid. Skipper writes this file after each successful fetch and reads it as a fallback on API failure
SKIPPER_SYNC_ALLOW_DELETE false When false, orphaned rows (tests removed from the suite) are only warned about. Set to true to delete them
SKIPPER_DEBUG Set to any truthy value to enable verbose logging

Modes

read-only (default)

No env var needed. Tests with a future disabledUntil are skipped.

SKIPPER_SPREADSHEET_ID=<id> pnpm test

sync (CI on merge to main)

SKIPPER_MODE=sync SKIPPER_SPREADSHEET_ID=<id> pnpm test

After the run:

  • New tests → added to the spreadsheet with empty disabledUntil
  • Removed tests → warned (set SKIPPER_SYNC_ALLOW_DELETE=true to also delete them)

CI Example (GitHub Actions)

# .github/workflows/test.yml
name: Test

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v3
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      - run: pnpm install

      - name: Test (read-only on PR)
        if: github.event_name == 'pull_request'
        env:
          SKIPPER_SPREADSHEET_ID: ${{ secrets.SKIPPER_SPREADSHEET_ID }}
          GOOGLE_CREDS_B64: ${{ secrets.GOOGLE_CREDS_B64 }}
        run: pnpm test

      - name: Test + sync (on merge to main)
        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: pnpm test

License

MIT — see LICENSE.

About

Enable and disable tests directly from a Google Spreadsheet — no code changes required.

Resources

License

Contributing

Stars

Watchers

Forks

Contributors