Agent skill

Playwright Testing

by podman-desktop in podman-desktop/extension-bootc

Guides writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension.

Apache-2.0Auto-check passedTesting & QA

Install Playwright Testing

skills CLI
$ npx skills add podman-desktop/extension-bootc --skill playwright-testing -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install podman-desktop/extension-bootc playwright-testing --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/podman-desktop/extension-bootc.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/playwright-testing .claude/skills/playwright-testing && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
playwright-testing
GitHub stars
474
Token cost
~2.6k tokens
SKILL.md length
585 words
Files
1
Skills in repo
5
Repo updated
First seen
Licence
Apache-2.0

At a glance

Guides writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension.

  • Works in 5 steps: Clicks the "Bootable Containers" link in… → Waits for the webview document to appear → Gets the second Electron window via… → …
  • Modifying E2E spec files
  • SKILL.md covers Project Structure, Critical Concept: Webview…, Imports and Extension Lifecycle Management, plus 7 more sections
  • Calls pnpm

What it does

Playwright Testing is an agent skill from podman-desktop/extension-bootc. Guides writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension. Covers the webview-aware test framework, extension lifecycle management, Page Object Models, and spec file patterns. Triggers when creating or modifying E2E spec files, building page object models, debugging Playwright failures, or asking about the test framework.

Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Browser testing and End-to-end testing. It works with Playwright. The repository describes itself as: Support for bootable OS containers (bootc) and generating disk images. The licence is Apache-2.0.

When your agent uses it

  • Modifying E2E spec files
  • Building page object models
  • Debugging Playwright failures
  • Asking about the test framework

Example prompts

  • “Use the playwright-testing skill to guide writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension”
  • “/playwright-testing”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Clicks the "Bootable Containers" link in Podman Desktop's main navigation
  2. Waits for the webview document to appear
  3. Gets the second Electron window via runner.getWindows()
  4. Focuses the webview element
  5. Returns [mainPage, webViewPage]

What it can do on your machine

Read from SKILL.md and the folder at commit 4230bcf. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Playwright Testing loads about 2.6k tokens when it runs. Until then it costs about 94 tokens; SKILL.md has 585 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~94
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from podman-desktop/extension-bootc at commit 4230bcf, republished under its Apache-2.0 licence (© podman-desktop). 585 words, ~2,632 tokens.

Download SKILL.mdSave it as .claude/skills/playwright-testing/SKILL.md (or your agent's skills folder).
name
playwright-testing
description
Guides writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension. Covers the webview-aware test framework, extension lifecycle management, Page Object Models, and spec file patterns. Triggers when creating or modifying E2E spec files, building page object models, debugging Playwright failures, or asking about the test framework.
paths
tests/playwright/**/*.ts

Playwright E2E Testing for Bootc Extension

This extension runs inside Podman Desktop as a webview. E2E tests launch Podman Desktop via Electron, install the extension from an OCI image, then interact with the extension's webview UI. This is fundamentally different from testing Podman Desktop itself — every test must handle the webview boundary.

Project Structure

Tests live in tests/playwright/. Key directories:

  • src/*.spec.ts — test spec files
  • src/model/ — Page Object Models (webview-aware, take both page and webview)
  • src/utility/ — test helpers (webview handling, extension lifecycle, cleanup)
bash
# See the full structure
find tests/playwright/src -type f -name '*.ts' | sort

Critical Concept: Webview Handling

Extensions render in a webview (a separate Electron BrowserWindow). You must get BOTH the main page and the webview page to interact with extension UI:

typescript
import { handleWebview } from './utility/bootc-test-utils';

// Returns [mainPage, webViewPage] — use webViewPage for extension UI locators
const [page, webview] = await handleWebview(runner);

How handleWebview() works:

  1. Clicks the "Bootable Containers" link in Podman Desktop's main navigation
  2. Waits for the webview document to appear
  3. Gets the second Electron window via runner.getWindows()
  4. Focuses the webview element
  5. Returns [mainPage, webViewPage]

All extension Page Object Models take both page and webview parameters. Use webview for extension-specific locators, page for Podman Desktop dialogs.

Imports

Import test, expect, and utilities from @podman-desktop/tests-playwright:

typescript
import {
  test,
  expect as playExpect,
  RunnerOptions,
  removeFolderIfExists,
  waitForPodmanMachineStartup,
  NavigationBar,
  waitUntil,
} from '@podman-desktop/tests-playwright';
import type { Page } from '@playwright/test';

Import extension-specific models and utilities locally:

typescript
import { BootcNavigationBar } from './model/bootc-navigationbar';
import {
  handleWebview,
  installBootcExtensionIfNeeded,
  removeBootcExtensionIfNeeded,
  cleanupRawVideoFiles,
} from './utility/bootc-test-utils';
import { markTestFileComplete } from './utility/extension-lifecycle';

Extension Lifecycle Management

The extension is installed once before the first spec file and removed after the last one completes. This is managed by a file-based counter:

  1. global-setup.ts counts spec files and writes the total to a temp file
  2. Each spec's afterAll calls markTestFileComplete(fileId) which decrements
  3. When the counter reaches zero, the last spec file triggers removal
  4. extension-reporter.ts handles fully-skipped files (their afterAll never runs)

Every spec file MUST include this in its outer test.afterAll:

typescript
import { fileURLToPath } from 'node:url';
import { markTestFileComplete } from './utility/extension-lifecycle';

const __filename = fileURLToPath(import.meta.url);

test.afterAll(async ({ navigationBar }) => {
  if (markTestFileComplete(__filename)) {
    await removeBootcExtensionIfNeeded(navigationBar);
  }
});

Page Object Model Pattern

Two-Parameter POMs

Unlike upstream Podman Desktop POMs (which take only page), bootc POMs take both page and webview:

typescript
export class BootcDashboardPage {
  readonly page: Page;
  readonly webview: Page;
  readonly heading: Locator;

  constructor(page: Page, webview: Page) {
    this.page = page;
    this.webview = webview;
    // Extension UI locators use webview
    this.heading = webview.getByText('Welcome to bootable containers');
  }
}
Using POMs

POMs are in tests/playwright/src/model/. Read them for current methods and locators:

bash
ls tests/playwright/src/model/

The navigation bar POM navigates within the extension's webview. Other POMs wrap specific pages (build, dashboard, disk images, examples, etc.).

Dialog Handling

Build completion shows a dialog on the main page (not webview). Always use this.page (not this.webview) for Podman Desktop dialogs.

Writing a New Spec File

Template
typescript
import type { Page } from '@playwright/test';
import {
  removeFolderIfExists,
  waitForPodmanMachineStartup,
  test,
  expect as playExpect,
  RunnerOptions,
  isLinux,
} from '@podman-desktop/tests-playwright';
import * as path from 'node:path';
import { fileURLToPath } from 'node:url';
import { BootcNavigationBar } from './model/bootc-navigationbar';
import {
  removeBootcExtensionIfNeeded,
  handleWebview,
  installBootcExtensionIfNeeded,
  cleanupRawVideoFiles,
} from './utility/bootc-test-utils';
import { markTestFileComplete } from './utility/extension-lifecycle';

let page: Page;
let webview: Page;
const __filename = fileURLToPath(import.meta.url);

test.use({
  runnerOptions: new RunnerOptions({
    customFolder: 'bootc-tests-pd',
    customOutputFolder: 'tests/output',
    autoUpdate: false,
    autoCheckUpdates: false,
  }),
});

test.beforeAll(async ({ runner, welcomePage, page }) => {
  await removeFolderIfExists('tests/output/images');
  runner.setVideoAndTraceName('my-feature-name');
  await welcomePage.handleWelcomePage(true);
  await waitForPodmanMachineStartup(page);
});

test.afterAll(async ({ runner }) => {
  test.setTimeout(320_000);
  const videoAndTraceName = runner.getVideoAndTraceName();
  try {
    await removeFolderIfExists('tests/output/images');
  } finally {
    await runner.close(200_000);
    cleanupRawVideoFiles('tests/output', videoAndTraceName);
  }
});

test.describe('My Feature', () => {
  test.skip(isLinux); // building bootable images not supported on Linux

  test.beforeAll(async ({ navigationBar }) => {
    test.setTimeout(200_000);
    await installBootcExtensionIfNeeded(navigationBar);
  });

  test.describe.serial('Feature flow', () => {
    test('Navigate to extension', async ({ runner }) => {
      test.setTimeout(60_000);
      [page, webview] = await handleWebview(runner);
      const bootcNav = new BootcNavigationBar(page, webview);
      const dashboard = await bootcNav.openBootcDashboard();
      await playExpect(dashboard.heading).toBeVisible();
    });

    test('Perform action', async ({ runner }) => {
      test.setTimeout(300_000);
      [page, webview] = await handleWebview(runner);
      // ... test body
    });
  });

  test.afterAll(async ({ navigationBar }) => {
    if (markTestFileComplete(__filename)) {
      await removeBootcExtensionIfNeeded(navigationBar);
    }
  });
});
Show full SKILL.md (238 more words)Show less
Key Patterns
  • Always call handleWebview(runner) at the start of each test that interacts with the extension
  • Use test.describe.serial() — tests share Electron state and must run in order
  • Use test.skip(isLinux) — building bootable images is not supported on Linux
  • Long timeouts are normal — image pulls take up to 12 minutes, builds up to 25 minutes
  • Clean up video files — call cleanupRawVideoFiles() in afterAll to handle orphaned webview recordings
  • customFolder: 'bootc-tests-pd' — all specs use this folder name for consistent profile isolation
Platform Skip Patterns
typescript
import { isLinux, isMac, isWindows } from '@podman-desktop/tests-playwright';

test.skip(isLinux); // no bootable image building on Linux
test.skip(isMac && arch === ArchitectureType.AMD64, 'amd64 not supported on macOS');
test.skip(isWindows && arch === ArchitectureType.ARM64, 'arm64 not supported on Windows');

Extension Installation

The extension is installed from an OCI image. The URL is configurable:

typescript
// Default: ghcr.io/podman-desktop/extension-bootc:next
// Override: set OCI_IMAGE env var
const extensionURL = process.env.OCI_IMAGE ?? 'ghcr.io/podman-desktop/extension-bootc:next';

Set SKIP_INSTALLATION=true to skip install/remove (when testing with a pre-installed extension).

Running Tests

bash
# From the repo root
pnpm test:e2e

# From tests/playwright directly
pnpm --dir tests/playwright test:e2e

# Run a single spec
pnpm --dir tests/playwright exec playwright test src/bootc-dashboard.spec.ts

# With custom extension image
OCI_IMAGE=ghcr.io/podman-desktop/extension-bootc:v1.15.0 \
  pnpm --dir tests/playwright exec playwright test src/

# Skip extension install/remove (pre-installed)
SKIP_INSTALLATION=true \
  pnpm --dir tests/playwright exec playwright test src/
Environment Variables
VariablePurpose
PODMAN_DESKTOP_BINARYPath to Podman Desktop binary
PODMAN_DESKTOP_ARGSPath to Podman Desktop repo (dev mode)
OCI_IMAGEExtension OCI image URL (default: next tag)
SKIP_INSTALLATIONSkip extension install/remove lifecycle
BUILD_ISO_IMAGEEnable ISO build tests (disabled by default)

Existing Spec Files

bash
# List all spec files and their test descriptions
ls tests/playwright/src/*.spec.ts
grep -h "test.describe\|test('" tests/playwright/src/*.spec.ts

Troubleshooting

Webview Not Appearing

If handleWebview() times out waiting for the second window, the extension may not have loaded. Check that the extension is installed and in ACTIVE state.

Build Stuck in "creating" State

BootcPage.refreshPageWhileInCreatingState() navigates away and back to force a UI refresh. The waitUntil wrapper retries until the state changes.

Video File Cleanup

Webview windows generate orphaned raw video files (32-char hex names). cleanupRawVideoFiles() handles this — always call it in afterAll.

Discovering POM APIs

Read the actual Page Object Models to see current locators and methods:

bash
# List all POMs
ls tests/playwright/src/model/

# Read a specific POM for its locators and methods
cat tests/playwright/src/model/bootc-page.ts

# List all test utilities
cat tests/playwright/src/utility/bootc-test-utils.ts

© podman-desktop, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/playwright-testing of podman-desktop/extension-bootc.

Open the folder on GitHubat commit 4230bcf

Compare with similar skills

Playwright Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Playwright Testing compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Playwright Testing this skillpodman-desktop/extension-bootc474—~2.6kAutomated safety check: PassApache-2.0
Web Application Testinganthropics/skills180k51 repos~966Automated safety check: PassApache-2.0
playwright-cli Browser Automationgithub/gh-aw5.4k24 repos~2.8kAutomated safety check: PassMIT
Write and Verify Playwright Testsappsmithorg/appsmith41k—~2.9kAutomated safety check: NotesApache-2.0
Cucumber and Playwright E2E Testslanggenius/dify158k—~682Automated safety check: PassCustom licence
E2E Testinglangflow-ai/langflow156k—~3.3kAutomated safety check: PassMIT

Similar skills

  • Web Application Testing

    anthropics/skills

    Official

    Tests local web applications with Python Playwright scripts, checking frontend behavior, capturing screenshots and reading browser console logs.

    180k GitHub starsUsed in 51 repos~966 tokens
    Testing & QAAuto-check passed
  • Official

    Drives a real browser from the command line with playwright-cli to open pages, interact, mock requests, save state and work with Playwright tests.

    5.4k GitHub starsUsed in 24 repos~2.8k tokens
    Testing & QAAuto-check passed
  • Writes a Playwright end-to-end test from a prompt, runs it against a live Appsmith deployment and retries with fixes up to three times until it passes.

    41k GitHub stars~2.9k tokensUpdated today
    Testing & QAAuto-check: notes
  • Guides changes and reviews of the Cucumber and Playwright end-to-end suite under `e2e/`: feature files, step definitions, support code, tags, locators and assertions.

    158k GitHub stars~682 tokensUpdated today
    Testing & QAAuto-check passed
  • E2E Testing

    langflow-ai/langflow

    Write and review Playwright E2E tests for Langflow. An agent skill from langflow-ai/langflow.

    156k GitHub stars~3.3k tokensUpdated today
    Testing & QAAuto-check passed
  • Handsontable Playwright E2E Tests

    handsontable/handsontable

    Guides writing and changing Playwright end-to-end tests for Handsontable using page objects, data-testid hooks and deterministic waits.

    22k GitHub stars~1.8k tokensUpdated today
    Testing & QAAuto-check passed

More from podman-desktop/extension-bootc

  • Backend API

    podman-desktop/extension-bootc

    Guides backend development with @podman-desktop/api and the bootc extension's RPC system.

    474 GitHub stars~1k tokensUpdated today
    Auto-check passed
  • Extension Development

    podman-desktop/extension-bootc

    Guides end-to-end feature development in the bootc Podman Desktop extension.

    474 GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Svelte UI Design

    podman-desktop/extension-bootc

    Guides designing and building Svelte 5 UI components in the bootc extension.

    474 GitHub stars~1.3k tokensUpdated today
    Auto-check passed
  • Unit Testing

    podman-desktop/extension-bootc

    Guides writing and maintaining Vitest unit tests for the bootc extension's backend, frontend, and shared packages.

    474 GitHub stars~1.4k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Playwright Testing

What does Playwright Testing do?

Guides writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension. Playwright Testing is an agent skill from podman-desktop/extension-bootc. Guides writing and maintaining Playwright E2E tests for the bootc Podman Desktop extension.

When should I use Playwright Testing?

Playwright Testing fits situations like: modifying E2E spec files; building page object models; debugging Playwright failures; asking about the test framework.

How do I install Playwright Testing in Claude Code?

Run `npx skills add podman-desktop/extension-bootc --skill playwright-testing -a claude-code`. Or copy the skill folder (.agents/skills/playwright-testing in podman-desktop/extension-bootc) into .claude/skills/playwright-testing in your project. Claude Code loads it when a task matches its description.

How do I install Playwright Testing in Codex?

Run `npx skills add podman-desktop/extension-bootc --skill playwright-testing -a codex`. Or copy the skill folder (.agents/skills/playwright-testing in podman-desktop/extension-bootc) into .agents/skills/playwright-testing in your project. Codex loads it when a task matches its description.

Can I use Playwright Testing in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add podman-desktop/extension-bootc --skill playwright-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/playwright-testing, .gemini/skills/playwright-testing, .github/skills/playwright-testing and .opencode/skills/playwright-testing in your project.

What does Playwright Testing need to run?

Going by SKILL.md and its folder, Playwright Testing needs the command-line tools its instructions call (pnpm).

Does Playwright Testing access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Playwright Testing safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Playwright Testing use?

Playwright Testing is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Playwright Testing use?

About 2.6k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Playwright Testing?

Skills that share tags, products or a category with Playwright Testing: Web Application Testing (anthropics/skills, 180k stars), playwright-cli Browser Automation (github/gh-aw, 5.4k stars), Write and Verify Playwright Tests (appsmithorg/appsmith, 41k stars) and Cucumber and Playwright E2E Tests (langgenius/dify, 158k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Playwright Testing?

podman-desktop (a GitHub organization) maintains it in podman-desktop/extension-bootc, which has 474 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on October 8, 2026.

Source: podman-desktop/extension-bootc on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.