Skip to content

playwright Pod

Standard OCI container - works with Docker, Podman, Kubernetes, Apptainer.

The playwright pod provides a complete browser automation environment with Playwright, Google Chrome, a Wayland compositor (Sway), and VNC access for visual debugging.

Overview

Attribute Value
Image ghcr.io/atrawog/bazzite-ai-pod-playwright:stable
Size ~5GB
GPU NVIDIA (optional, for GPU acceleration)
Inherits pod-nvidia
Port 5900 (VNC)

Quick Start

# With VNC access (connect to localhost:5900)
docker run -it --rm -p 5900:5900 -v $(pwd):/workspace \
  ghcr.io/atrawog/bazzite-ai-pod-playwright:stable

# With GPU acceleration
docker run -it --rm --gpus all --privileged -p 5900:5900 -v $(pwd):/workspace \
  ghcr.io/atrawog/bazzite-ai-pod-playwright:stable

# Headless only (no VNC)
docker run -it --rm -v $(pwd):/workspace \
  ghcr.io/atrawog/bazzite-ai-pod-playwright:stable bash
apiVersion: v1
kind: Pod
metadata:
  name: playwright-test
spec:
  containers:
  - name: playwright
    image: ghcr.io/atrawog/bazzite-ai-pod-playwright:stable
    ports:
    - containerPort: 5900
      name: vnc
    volumeMounts:
    - name: workspace
      mountPath: /workspace
  volumes:
  - name: workspace
    persistentVolumeClaim:
      claimName: test-workspace
apptainer pull docker://ghcr.io/atrawog/bazzite-ai-pod-playwright:stable
apptainer exec bazzite-ai-pod-playwright_stable.sif bash
apptainer pull docker://ghcr.io/atrawog/bazzite-ai-pod-playwright:stable
apptainer shell bazzite-ai-pod-playwright_stable.sif

What's Included

Browser Automation

Component Description
Playwright Browser automation framework (Python)
Google Chrome Full Chrome browser for testing
Playwright browsers Pre-installed browser binaries

Display Environment

Component Description
Sway Wayland compositor (tiling window manager)
wayvnc VNC server for remote access
s6-overlay Process supervision (container init)

VR/Streaming Support

Component Description
OpenVR VR headset support
OpenXR Cross-platform VR/AR API
OpenCV Computer vision library
GStreamer Media streaming framework

From nvidia Pod

  • CUDA Toolkit 13.0
  • cuDNN, TensorRT

From base Pod

  • Python, Node.js, VS Code, Docker CLI
  • kubectl, Helm, Claude Code

Usage

VNC Access

Connect with any VNC client:

  • Address: localhost:5900
  • Password: None (local development)

Recommended clients:

  • macOS: Built-in Screen Sharing (vnc://localhost:5900)
  • Linux: Remmina, TigerVNC
  • Windows: RealVNC, TightVNC

Running Playwright Tests

Inside the pod (via VNC or exec):

# Activate the environment
pixi shell --manifest-path /opt/pixi/pixi.toml

# Run tests
pytest tests/

# Or run directly
pixi run --manifest-path /opt/pixi/pixi.toml pytest tests/

Writing Playwright Tests

# tests/test_example.py
from playwright.sync_api import sync_playwright

def test_homepage():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto("https://example.com")

        assert page.title() == "Example Domain"

        browser.close()

def test_screenshot():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto("https://example.com")

        # Screenshot saved to /workspace
        page.screenshot(path="/workspace/screenshot.png")

        browser.close()

Async Playwright

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        await page.goto("https://example.com")

        # Interact with the page
        await page.click("text=More information")

        await browser.close()

asyncio.run(main())

Common Workflows

Visual Test Debugging

  1. Run pod with VNC
  2. Connect VNC client
  3. Run tests in headed mode (headless=False)
  4. Watch browser interactions in real-time

Screenshot Testing

def test_visual_regression():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto("https://myapp.com")

        # Compare to baseline
        page.screenshot(path="/workspace/screenshots/current.png")

        browser.close()

Form Testing

def test_login_form():
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        page.goto("https://myapp.com/login")

        # Fill form
        page.fill('input[name="email"]', 'test@example.com')
        page.fill('input[name="password"]', 'secret123')
        page.click('button[type="submit"]')

        # Verify redirect
        assert page.url == "https://myapp.com/dashboard"

        browser.close()

Environment Details

Display Configuration

Variable Value
XDG_RUNTIME_DIR /run/user/1000
WAYLAND_DISPLAY wayland-0
XDG_SESSION_TYPE wayland

Playwright Configuration

Variable Value
PLAYWRIGHT_BROWSERS_PATH /home/jovian/.cache/ms-playwright
PLAYWRIGHT_PROJECT /opt/pixi

Troubleshooting

VNC Connection Refused

  1. Ensure port 5900 is published: -p 5900:5900
  2. Check if Sway started: docker logs <container>
  3. Verify s6-overlay initialization

Browser Won't Launch

# Use explicit executable path
browser = p.chromium.launch(
    executable_path="/usr/bin/google-chrome-stable",
    headless=False
)

Display Issues

Ensure XDG_RUNTIME_DIR is writable:

ls -la /run/user/1000
# Should be owned by jovian:jovian with mode 700

No GPU Acceleration

  1. Verify NVIDIA runtime: --gpus all
  2. GPU is optional - pod works without it

See Also