Skip to content

Conditionally wrap pest with xvfb-run when available#855

Draft
JoshSalway wants to merge 3 commits intolaravel:1.xfrom
JoshSalway:fix/pest-xvfb-headed-browser
Draft

Conditionally wrap pest with xvfb-run when available#855
JoshSalway wants to merge 3 commits intolaravel:1.xfrom
JoshSalway:fix/pest-xvfb-headed-browser

Conversation

@JoshSalway
Copy link
Copy Markdown

@JoshSalway JoshSalway commented Mar 22, 2026

Summary

Fixes #815 - Pest v4 browser tests fail in headed mode inside Sail containers with "XServer not running" error because the pest command lacks a virtual display server.

This PR wraps the pest command with xvfb-run only when xvfb-run is available in the container. Stock Sail containers that have not run npx playwright install-deps do not have xvfb-run installed, so unconditionally wrapping the command would break sail pest for those users.

Steps to Reproduce

  1. Set up a Laravel project using Sail with Pest v4 and pest-plugin-browser
  2. Write a browser test that uses headed mode (e.g., $page = visit('/')->debug())
  3. Run sail pest tests/Browser
  4. Observe Playwright error: "XServer not running"

Before (Bug)

Target page, context or browser has been closed
Browser logs:
Looks like you launched a headed browser without having a XServer running.
Set either 'headless: true' or use 'xvfb-run'

PR #812 added Playwright support to Sail (including npx playwright install-deps which installs xvfb), but the sail pest command runs Pest directly without wrapping it in a virtual display. Headed Playwright tests require an X display server.

After (Fix)

Browser tests run successfully inside the container. xvfb-run provides a virtual framebuffer that enables headed Playwright tests to work transparently. Non-browser Pest tests are unaffected (xvfb-run is transparent for tests that do not use a display).

The Fix

Conditionally wraps the pest command with xvfb-run only when it is available in the container:

-ARGS+=("$APP_SERVICE" php vendor/bin/pest)
+if "${COMPOSE_CMD[@]}" exec -T "$APP_SERVICE" command -v xvfb-run &> /dev/null; then
+    ARGS+=("$APP_SERVICE" xvfb-run php vendor/bin/pest)
+else
+    ARGS+=("$APP_SERVICE" php vendor/bin/pest)
+fi

This ensures:

  • Containers with Playwright/xvfb installed get the xvfb-run wrapper for headed browser tests
  • Stock containers without xvfb continue to work as before

Breaking Changes

None. The check is backward-compatible with all Sail containers.

Files Changed

  • bin/sail - Conditionally wrap pest command with xvfb-run when available

@github-actions
Copy link
Copy Markdown

Thanks for submitting a PR!

Note that draft PRs are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

Josh Salway and others added 3 commits April 1, 2026 14:37
Pest v4 browser tests in headed mode (e.g. using debug()) fail with
"Looks like you launched a headed browser without having a XServer
running" because the Sail container has no display server.

Wrap the pest command with xvfb-run to provide a virtual framebuffer.
This is transparent for non-browser tests and enables headed Playwright
browser tests to work inside the container.

Fixes laravel#815

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only wrap pest with xvfb-run when it is actually installed in the
container. Stock Sail containers without Playwright do not have
xvfb-run, so unconditionally using it breaks sail pest for users
who have not run npx playwright install-deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pest v4 browser tests fail in headed mode on Sail (WSL): XServer not running

1 participant