Files
paskia/e2e
LeoVasanko 68dccc1378 OAuth2 OpenID Connect provider support, API and DB refactoring (#3)
Allows Paskia to authenticate the user to a client site.
- User friendly client registration flow on the admin app
- Redirect-based authentication flow (per spec)
- Backchannel logout both ways to keep sessions synchronized
- Groups integrated with Paskia's permission system
- Adds email, preferred username and telephone fields on user profile
- All new user basic info layout to show the new information, better looks
- API and DB structures redesigned
- Various unrelated fixes to theming and layout
2026-02-18 02:40:27 +00:00
..

Paskia E2E Tests

End-to-end tests for Paskia using Playwright with Chrome's Virtual Authenticator.

Overview

These tests exercise the complete WebAuthn/passkey authentication flow without requiring physical hardware. Chrome's DevTools Protocol provides a virtual authenticator that can:

  • Generate passkey credentials
  • Sign authentication challenges
  • Store resident keys (discoverable credentials)
  • Simulate user verification (biometrics/PIN)

Prerequisites

  • Node.js 18+
  • Python with uv (for running the backend server)

Setup

cd e2e
npm install
npm run install:browsers

Running Tests

Basic Test Run

npm test

This will:

  1. Start a fresh Paskia server with a test database
  2. Run all E2E tests against it
  3. Clean up the server when done

With Coverage

npm run test:coverage

Runs tests and collects coverage for both:

  • Python backend (via coverage.py) - HTML report in coverage-html/
  • Frontend JavaScript (via Chrome V8 coverage) - JSON data in e2e/coverage-frontend/

Interactive Mode

npm run test:ui

Opens Playwright's UI mode for interactive test debugging.

Headed Mode

npm run test:headed

Runs tests with a visible browser window.

Debug Mode

npm run test:debug

Runs tests with Playwright Inspector for step-by-step debugging.

Test Structure

e2e/
├── playwright.config.ts      # Playwright configuration
├── package.json
├── tsconfig.json
├── test-data/                # Test database (created at runtime)
│   └── test.sqlite
└── tests/
    ├── global-setup.ts       # Creates fresh DB, captures reset token
    ├── global-teardown.ts    # Cleanup
    ├── passkey.spec.ts       # Main E2E tests
    └── fixtures/
        ├── virtual-authenticator.ts  # Virtual authenticator setup
        └── passkey-helpers.ts        # WebSocket helpers

What's Tested

Registration Flow

  • Bootstrap admin user registration via reset token
  • WebSocket challenge-response with virtual authenticator
  • Session token creation and validation

Authentication Flow

  • Passkey authentication via WebSocket
  • Credential verification
  • Session management

Session Management

  • Token validation (/auth/api/validate)
  • User info retrieval (/auth/api/user-info)
  • Logout (/auth/api/logout)
  • Invalid/missing token rejection

How Virtual Authenticator Works

The tests use Chrome DevTools Protocol (CDP) to create a virtual authenticator:

const cdpSession = await page.context().newCDPSession(page)
await cdpSession.send('WebAuthn.enable')
await cdpSession.send('WebAuthn.addVirtualAuthenticator', {
  options: {
    protocol: 'ctap2',
    transport: 'internal',
    hasResidentKey: true,
    hasUserVerification: true,
    isUserVerified: true,
    automaticPresenceSimulation: true,
  },
})

This creates an in-browser authenticator that:

  • Automatically responds to WebAuthn prompts
  • Stores credentials persistently during the test session
  • Simulates user verification without actual biometric input

Environment Variables

Variable Description Default
BASE_URL Server URL http://localhost:4404
CI CI environment flag -
CLEANUP_TEST_DB Remove test DB after run false

Limitations

  1. Chromium only: Virtual authenticator is a Chrome DevTools feature
  2. No cross-origin: Tests run on localhost; production-like origins need additional setup
  3. Single user per run: Bootstrap creates one admin user; additional users need admin API

Debugging Tips

  1. Check test database: e2e/test-data/test.sqlite persists after tests
  2. View server output: Global setup echoes server bootstrap to console
  3. Use trace viewer: npx playwright show-trace on failure traces

CI Integration

The tests are designed for CI environments:

- name: Run E2E Tests
  run: |
    cd e2e
    npm ci
    npm run install:browsers
    npm test
  env:
    CI: true