From 9bb26bd715c0083e60ef4cbfcee2ae62ef77d077 Mon Sep 17 00:00:00 2001 From: mshriver Date: Tue, 21 Jul 2026 10:35:19 -0400 Subject: [PATCH] Add script to handle PW dependency install the playwright dependency installer only handles apt-get and explicitly will not be handling any other operating systems provide a script, run through hatch, to handle playwright dependency install Co-authored-by: Claude --- pyproject.toml | 28 +++++++ scripts/install_playwright_deps.py | 125 +++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 scripts/install_playwright_deps.py diff --git a/pyproject.toml b/pyproject.toml index c275be7..da92e1b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,6 +52,34 @@ packages = ["src/widgetastic_patternfly5"] source = "vcs" raw-options.version_scheme = "calver-by-date" +[tool.hatch.envs.test] +features = ["dev"] + +[tool.hatch.envs.test.scripts] +# Installs browser binaries and Linux system-level dependencies. +# Run once after setting up the environment: hatch run test:install-browsers +install-browsers = [ + "playwright install chromium firefox", + "python scripts/install_playwright_deps.py", +] +# Run all tests (headless) – PF version defaults to v6 per conftest +all = "pytest -v --headless {args}" +# PF-version-specific convenience scripts used locally and in CI +pf5 = "pytest -v --headless --pf-version=v5 {args}" +pf6 = "pytest -v --headless --pf-version=v6 {args}" +# Headed mode for local interactive debugging +debug = "pytest -v --pf-version=v6 {args}" + +[tool.hatch.envs.lint] +dependencies = ["pre-commit"] + +[tool.hatch.envs.lint.scripts] +check = "pre-commit run --all-files" + +[tool.pytest.ini_options] +testpaths = ["testing"] +timeout = 60 + [tool.ruff] line-length = 100 diff --git a/scripts/install_playwright_deps.py b/scripts/install_playwright_deps.py new file mode 100644 index 0000000..c9c3a8a --- /dev/null +++ b/scripts/install_playwright_deps.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +"""Install Playwright system dependencies in an OS-agnostic way. + +Playwright's ``install-deps`` only supports Debian/Ubuntu (apt-get). This +helper detects the package manager and either delegates to Playwright or +installs the equivalent RPM packages on Fedora/RHEL. +""" + +from __future__ import annotations + +import os +import platform +import shutil +import subprocess +import sys + +# Packages needed for Chromium and Firefox on Fedora/RHEL. +# Mapped from Playwright's Debian dependency list; see: +# https://github.com/microsoft/playwright/issues/27890 +FEDORA_PACKAGES = [ + "nspr", + "nss", + "dbus-libs", + "atk", + "at-spi2-atk", + "cups-libs", + "at-spi2-core", + "libX11", + "libXcomposite", + "libXdamage", + "libXext", + "libXfixes", + "libXrandr", + "mesa-libgbm", + "libxcb", + "libxkbcommon", + "pango", + "cairo", + "alsa-lib", + "libdrm", + "gtk3", +] + + +def _run(cmd: list[str]) -> None: + print(f"+ {' '.join(cmd)}", flush=True) + subprocess.run( + cmd, check=True + ) # nosemgrep: python.lang.security.audit.dangerous-subprocess-use-audit + + +def _install_debian() -> None: + print("Detected apt-get; delegating to playwright install-deps.") + _run(["playwright", "install-deps"]) + + +def _install_fedora() -> None: + dnf = shutil.which("dnf") or shutil.which("yum") + if dnf is None: + raise RuntimeError("Neither dnf nor yum found on PATH") + + print(f"Detected RPM-based system ({dnf}); installing Playwright library dependencies.") + cmd = [dnf, "install", "-y", *FEDORA_PACKAGES] + if os.geteuid() != 0: + if shutil.which("sudo") is None: + raise RuntimeError( + "Root privileges are required to install system packages, " + "but sudo was not found. Re-run as root or install sudo." + ) + cmd = ["sudo", *cmd] + _run(cmd) + + +def _skip_macos() -> None: + print("macOS detected; Playwright browsers bundle their own dependencies. Nothing to do.") + + +def _unsupported(system: str) -> None: + packages = " ".join(FEDORA_PACKAGES) + print( + f"Unsupported platform for automatic Playwright system deps: {system!r}.\n" + "Install browser system libraries manually, then re-run tests.\n\n" + "Debian/Ubuntu:\n" + " playwright install-deps\n\n" + "Fedora/RHEL:\n" + f" sudo dnf install -y {packages}\n", + file=sys.stderr, + ) + sys.exit(1) + + +def main() -> None: + system = platform.system() + + if system == "Darwin": + _skip_macos() + return + + if system == "Windows": + print("Windows detected; Playwright manages browser dependencies. Nothing to do.") + return + + if system != "Linux": + _unsupported(system) + + if shutil.which("apt-get"): + _install_debian() + return + + if shutil.which("dnf") or shutil.which("yum"): + _install_fedora() + return + + _unsupported(system) + + +if __name__ == "__main__": + try: + main() + except subprocess.CalledProcessError as exc: + print(f"Command failed with exit code {exc.returncode}: {exc.cmd}", file=sys.stderr) + sys.exit(exc.returncode) + except RuntimeError as exc: + print(str(exc), file=sys.stderr) + sys.exit(1)