BDD functional tests for the Keylime Monitoring Dashboard using Playwright + cucumber-js in TypeScript.
Tests validate the SRS requirements (95 FRs, 28 NFRs, 30 SRs with Gherkin acceptance criteria) against two deployment modes:
- Standalone: React SPA on
:5173with JWT authentication - Cockpit: Cockpit plugin on
:9090with PAM authentication (iframe)
- Node.js >= 22
- Google Chrome or Chromium installed on the system
- Rust toolchain (for building the backend)
- Mockoon CLI (installed as dev dependency)
- Sibling repos cloned:
keylime-webtool-backend,keylime-webtool-frontend,keylime-webtool-cockpit-plugin
npm install
npx playwright install chrome # downloads Chrome for Testing (Debian/Ubuntu)On Fedora/RHEL where playwright install-deps is not supported, install Google Chrome or Chromium system-wide instead:
sudo dnf install google-chrome-stable # or: sudo dnf install chromium- Start Mockoon mocks (upstream Keylime API simulation):
mockoon-cli start --data ../keylime-webtool-backend/test-data/verifier.json --port 3000 &
mockoon-cli start --data ../keylime-webtool-backend/test-data/registrar.json --port 3001 &- Start the backend:
cd ../keylime-webtool-backend
KEYLIME_VERIFIER_URL=http://localhost:3000 \
KEYLIME_REGISTRAR_URL=http://localhost:3001 \
DATABASE_URL=sqlite::memory: \
cargo run &- Start the frontend:
cd ../keylime-webtool-frontend
npm run dev &npm run test # all tests (standalone profile)
npm run test:standalone # standalone SPA tests
npm run test:cockpit # cockpit plugin tests
npm run test:api # API-only tests (no browser)
npm run test:dry # dry run (validate feature/step matching)npm run test -- --tags @FR-001 # single requirement
npm run test -- --tags "@smoke and not @wip" # tag expression
npm run test -- features/dashboard/FR-001-*.feature # single feature file
CUCUMBER_PROFILE=api npm run test # switch profile via env var| Variable | Default | Description |
|---|---|---|
HEADLESS |
true |
Run browser headless |
RECORD_VIDEO |
false |
Capture video on failure |
BASE_URL |
http://localhost:5173 |
Frontend URL |
API_BASE_URL |
http://localhost:8080 |
Backend URL |
JWT_SECRET |
test-secret-key |
JWT signing key |
SLOW_MO |
0 |
Playwright slow motion (ms) |
BROWSER_CHANNEL |
chrome |
Playwright browser channel (chrome, chromium, msedge) |
Place it in features/<domain>/ with SRS requirement tags:
@FR-042 @policies
Feature: Policy Version Rollback
As an operator
I want to rollback a policy to a previous version
So that I can revert unintended changes
Background:
Given the user is authenticated as "operator"
And the backend is running with Mockoon mocks
@standalone
Scenario: Rollback policy to previous version
Given the user is on the "Policies"
When the user rolls back policy "production-v1" to version 1
Then the policy version MUST be 1Create or extend files in src/steps/<domain>/:
import { When, Then } from "@cucumber/cucumber";
import { expect } from "@playwright/test";
import { CustomWorld } from "../../support/world.js";
import { PoliciesPage } from "../../pages/policies.page.js";
When(
"the user rolls back policy {string} to version {int}",
async function (this: CustomWorld, policyName: string, version: number) {
const page = new PoliciesPage(this);
// ... implementation
},
);Extend page objects in src/pages/ following the BasePage pattern. Use this.locator() which automatically handles cockpit iframe scoping.
| Tag | Meaning |
|---|---|
@FR-NNN |
Functional requirement from SRS |
@NFR-NNN |
Non-functional requirement |
@SR-NNN |
Security requirement |
@smoke |
Smoke test (fast subset) |
@standalone |
Runs only in standalone mode |
@cockpit |
Runs only in cockpit mode |
@api |
API-only test (no browser) |
@wip |
Work in progress (excluded from CI) |
@standalone-only |
Excluded from cockpit profile |
Test reports are generated in reports/:
cucumber-report.json— Raw cucumber JSON (sensitive data scrubbed)cucumber-report.html— HTML reporttraceability-matrix.html— Requirements coverage matrixtraceability-matrix.json— Machine-readable coverage data
Generate the traceability matrix after a test run:
npm run report:htmlGitHub Actions workflow (.github/workflows/e2e.yaml) runs three jobs:
- e2e-standalone — Full browser tests against standalone SPA
- e2e-api — API-only contract tests
- lint-typecheck — TypeScript + ESLint checks
Reports are uploaded as artifacts with 14-day retention.
Apache-2.0