Running Podman Desktop Interactively with Playwright
Instead of running the E2E test suite, you can launch Podman Desktop with the extension loaded and interact with it programmatically through Playwright's CDP connection. This is useful for manual exploration, AI-assisted interaction (e.g. with a Playwright MCP server), or ad-hoc scripting.
All executable scripts are in the scripts/ directory alongside this file.
Prerequisites
Complete the following from the e2e-container skill before proceeding:
- Install prerequisites (
scripts/install-prerequisites.sh) - Step 1: Install a Podman Desktop testing binary — see below
- Step 2: Build the extension plugin (
scripts/build-extension-plugin.sh) - Step 3: Start the envtest Kubernetes cluster (
scripts/start-envtest.sh)
Podman Desktop Binary
Podman Desktop may already be installed on the system (e.g., at
/usr/local/lib/podman-desktop/). Before running install-pd-binary.sh,
check if the binary exists:
which podman-desktop || ls /usr/local/lib/podman-desktop/podman-desktop
If it is already installed but not at the path expected by the launch script
(tests/playwright/tests/PodmanDesktop/podman-desktop), create symlinks:
ln -sf /usr/local/lib/podman-desktop/podman-desktop \
tests/playwright/tests/PodmanDesktop/podman-desktop
ln -sf /usr/local/lib/podman-desktop/podman-desktop.real \
tests/playwright/tests/PodmanDesktop/podman-desktop.real
Only run install-pd-binary.sh if Podman Desktop is not installed at all.
xdpyinfo
The xdpyinfo tool is required to detect the Xvfb display resolution. Install
it if not available:
sudo dnf install -y xdpyinfo
Verify Shared Library Dependencies
Before launching Podman Desktop, check that all shared libraries required by the Electron binary are available:
ldd tests/playwright/tests/PodmanDesktop/podman-desktop.real | grep "not found"
If any libraries are missing, install them using the prerequisites script from
the e2e-container skill.
Bootstrap Checklist
Before launching, verify each dependency is ready. The launch-podman-desktop.sh
script runs these checks automatically and will abort with clear error messages
if anything is missing:
| Check | How to verify | Fix |
|---|---|---|
| Xvfb running | [ -e /tmp/.X11-unix/X99 ] |
Run start-xvfb.sh |
| D-Bus system bus | [ -S /run/dbus/system_bus_socket ] |
Run start-xvfb.sh |
| PD binary exists | [ -x tests/playwright/tests/PodmanDesktop/podman-desktop ] |
Create symlinks or run install-pd-binary.sh |
| Shared libraries | ldd ...podman-desktop.real | grep "not found" — empty |
Install missing libs |
| envtest kubeconfig | [ -f /tmp/envtest-kubeconfig ] |
Run start-envtest.sh |
| Extension plugin | [ -d .../plugins/extension/dist ] |
Run build-extension-plugin.sh |
Important: Do NOT use pgrep -f to check for running processes — it
matches the shell process executing the grep command, giving false positives.
Use filesystem markers (/tmp/.X11-unix/X99, /run/dbus/system_bus_socket)
instead.
Launch Podman Desktop
Step 1: Start Xvfb and D-Bus
bash skills/interactive-podman-desktop/scripts/start-xvfb.sh
This script is idempotent — it checks filesystem markers before starting
services, and will restart Xvfb if the resolution doesn't match. Default
resolution is 1024x768 (matching the video recording size). Override with
XVFB_RESOLUTION=1920x1080 if needed.
Step 2: Create the Podman Desktop profile and launch
bash skills/interactive-podman-desktop/scripts/launch-podman-desktop.sh
This script:
- Runs pre-flight checks (all items in the Bootstrap Checklist above)
- Creates a profile with unnecessary extensions disabled
- Copies the envtest kubeconfig to
~/.kube/config - Launches Podman Desktop with CDP on port 9222
- Waits up to 20s for the CDP endpoint to become available
- Maximizes the window to fill the Xvfb display
No manual verification needed — the script reports success or failure.
Connecting with Playwright
From a Node.js script
const { chromium } = require('playwright');
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const pages = browser.contexts()[0].pages();
// pages[0] is the Podman Desktop shell
// pages[1] is the Kubernetes Dashboard extension webview (available after
// clicking the "Kubernetes" link in the sidebar)
const page = pages[0];
await page.screenshot({ path: 'screenshot.png' });
await browser.close();
From a Playwright MCP server
Connect the MCP server to the same http://127.0.0.1:9222 CDP endpoint. After
clicking the Kubernetes link in the sidebar, the extension webview opens as
a separate tab (tab index 1) — switch to it to interact with the Kubernetes
Dashboard.
WARNING: Do NOT use browser_navigate when connected via CDP to an Electron
app. It navigates the app's own window to the given URL, destroying the app UI.
Use only browser_snapshot, browser_click, browser_find, and browser_tabs.
Tips for Playwright MCP Interaction
Tab Management
Confirmation dialogs (e.g., delete confirmations) appear on the main Podman Desktop tab (tab index 0), not on the extension webview tab (tab index 1). When triggering an action from the extension that opens a dialog, switch to tab 0 to find and interact with the dialog, then switch back to tab 1.
Monaco Editor
The Monaco code editor (used in Patch and Apply tabs) does not respond to
Playwright's pressSequentially or fill methods. To type into Monaco:
- Click on a
div.view-lineelement at the target line. - Use individual key presses:
Endto move to end of line,Enterto create a new line. - Type content character by character using
browser_press_key.
Handling auto-indent
Monaco auto-indents new lines, but the indentation level it chooses is unpredictable — especially inside YAML arrays, where it may align to a new array element or inside the current element depending on context. Do not rely on Monaco's auto-indent being correct.
Instead, use the Enter → Shift+Home → Delete sequence to bypass auto-indent entirely:
- Press
Enter— Monaco creates a new line with auto-indented whitespace. - Press
Shift+Home— selects all auto-indent whitespace from cursor to the start of the line. - Press
Delete— removes the selected whitespace, placing the cursor at column 0. - Type the line with exact leading spaces (e.g.,
- kind: Userwith 2 spaces, orname: evewith 4 spaces).
This guarantees the cursor starts at column 0, giving you full control over indentation regardless of what Monaco's auto-indent would have done.
Why not Backspace? Monaco's smart Backspace jumps by tab stops and may land at the wrong column. Shift+Home → Delete is deterministic.