Skip to Content

FilesystemAdapter

Writes test results to JSON files on the local filesystem.

Installation

import { FilesystemAdapter } from '@lytics/playwright-adapters/filesystem';

Overview

The FilesystemAdapter is useful for:

  • Local development — Debug test results without external services
  • CI artifacts — Store results for later analysis
  • Offline usage — No network dependencies

Configuration

interface FilesystemAdapterConfig { /** Directory to write test results to (required) */ outputDir: string; /** Whether to pretty-print JSON (default: true) */ pretty?: boolean; }

Usage

Basic Usage

Create a reporter file:

// reporter.ts import { CoreReporter } from '@lytics/playwright-reporter'; import { FilesystemAdapter } from '@lytics/playwright-adapters/filesystem'; class CustomReporter extends CoreReporter { constructor() { super({ adapters: [ new FilesystemAdapter({ outputDir: './test-results', }), ], }); } } export default CustomReporter;

Reference it in your config:

// playwright.config.ts export default { reporter: [['list'], ['./reporter.ts']], };

With Options

new FilesystemAdapter({ outputDir: './test-results', pretty: true, // Pretty-print JSON (default: true) })

Compact JSON

For smaller file sizes:

new FilesystemAdapter({ outputDir: './test-results', pretty: false, // Minified JSON })

Output Structure

The adapter creates an organized directory structure:

test-results/ ├── test-results/ │ ├── ACCOUNT_SECURITY_VIEW-TOKENS_VALID-2024-01-01T00-00-00.000Z.json │ ├── ACCOUNT_SECURITY_VIEW-TOKENS_EMPTY-2024-01-01T00-00-01.000Z.json │ └── USER_MANAGEMENT_CREATE-USER_VALID-2024-01-01T00-00-02.000Z.json └── test-runs/ ├── test-run-run-123-2024-01-01T00-00-00.000Z.json ├── test-run-run-456-2024-01-01T01-00-00.000Z.json └── latest.json

test-results/

Individual test result files, named by testCaseId and timestamp:

{ "testCaseId": "ACCOUNT_SECURITY_VIEW-TOKENS_VALID", "journeyId": "ACCOUNT_SECURITY_VIEW-TOKENS", "title": "user can view access tokens", "status": "passed", "projectName": "chromium", "durationMs": 1234, "timestamp": "2024-01-01T00:00:00.000Z", "buildId": "run-123", "annotations": { "testSuiteName": "ACCOUNT_SECURITY", "journeyId": "ACCOUNT_SECURITY_VIEW-TOKENS", "testCaseId": "ACCOUNT_SECURITY_VIEW-TOKENS_VALID" } }

test-runs/

Test run summary files:

{ "runId": "run-123", "timestamp": "2024-01-01T00:00:00.000Z", "overallStatus": "passed", "totalTests": 10, "totalExecutions": 12, "passed": 9, "failed": 1, "skipped": 0, "durationMs": 45000, "passRate": 0.9, "averageTestDuration": 4500, "slowestTestDuration": 12000, "flakyTests": 2, "environment": { "branch": "main", "commit": "abc123" } }

latest.json

A symlink/copy of the most recent test run for easy access:

# Quick access to latest results cat test-results/test-runs/latest.json | jq '.passRate'

Features

Automatic Directory Creation

The adapter automatically creates the output directory and subdirectories if they don’t exist.

Pretty-Printed JSON

By default, JSON is pretty-printed for readability. Set pretty: false for minified output.

Non-Blocking Errors

File write errors are logged but don’t throw, allowing other adapters to continue.

CI/CD Integration

GitHub Actions

- name: Run tests run: npx playwright test - name: Upload test results uses: actions/upload-artifact@v4 if: always() with: name: test-results path: test-results/ retention-days: 30

GitLab CI

test: script: - npx playwright test artifacts: when: always paths: - test-results/ expire_in: 30 days

Example Output

Test Result (passed)

{ "testCaseId": "ACCOUNT_SECURITY_VIEW-TOKENS_VALID", "journeyId": "ACCOUNT_SECURITY_VIEW-TOKENS", "title": "user can view access tokens", "status": "passed", "projectName": "chromium", "durationMs": 2341, "timestamp": "2024-01-15T10:30:00.000Z", "buildId": "github-run-12345", "reportLink": "https://artifacts.example.com/run-12345/report.html", "annotations": { "testSuiteName": "ACCOUNT_SECURITY", "journeyId": "ACCOUNT_SECURITY_VIEW-TOKENS", "testCaseId": "ACCOUNT_SECURITY_VIEW-TOKENS_VALID" } }

Test Result (failed)

{ "testCaseId": "ACCOUNT_SECURITY_VIEW-TOKENS_EMPTY", "journeyId": "ACCOUNT_SECURITY_VIEW-TOKENS", "title": "shows empty state when no tokens exist", "status": "failed", "projectName": "chromium", "durationMs": 5123, "timestamp": "2024-01-15T10:30:05.000Z", "buildId": "github-run-12345", "error": { "matcher": "toBeVisible", "expected": "visible", "actual": "hidden", "locator": "getByText('No tokens found')", "location": { "file": "tests/account-security.spec.ts", "line": 42, "column": 5 }, "message": "Expected element to be visible", "snippet": [ " test('shows empty state', async ({ page }) => {", " await page.goto('/settings/tokens');", " await expect(page.getByText('No tokens found')).toBeVisible();", " });" ] }, "annotations": { "testSuiteName": "ACCOUNT_SECURITY", "journeyId": "ACCOUNT_SECURITY_VIEW-TOKENS", "testCaseId": "ACCOUNT_SECURITY_VIEW-TOKENS_EMPTY" } }

Troubleshooting

Permission denied errors

Cause: The process doesn’t have write permissions to the output directory.

Solution: Ensure the directory is writable or use a different path.

Files not appearing

Cause: Tests don’t have required annotations.

Solution: Add journeyId and testCaseId annotations to all tests. Unannotated tests are skipped.

The FilesystemAdapter is included in @lytics/playwright-adapters — no additional dependencies required.

Last updated on