Encourage usage of Playwright UI mode where available.
Use version-less Playwright Docker image to stay current.
Replace deprecated docker-compose commands with docker compose.
Playwright is a test runner that uses real browsers to test web applications
(an alternative to tools like Selenium). By default, Playwright runs these
browsers in headless mode, which means the pages are loaded and tested without
opening the browser window. This is great when running entire test suites
locally, and in CI where having a bunch of rapidly opening windows would be
disconcerting. However, when it comes to writing or debugging individual tests,
it is convenient to open the browser in headed mode to actually see the page
being tested.
Playwright for JS includes UI mode to let you run end-to-end tests with a
graphical explorer and debugger, allowing you to view, run, and debug tests in a
real browser window. For other supported platforms (like Python), Playwright
includes the Playwright Inspector to conveniently launch the browser in headed
mode and a separate window to control test execution. The inspector is
launched by setting PWDEBUG=1 before calling playwright, and is compatible
with all browsers supported by Playwright (Safari, Chrome, and Firefox) in all
major operating systems.
Additionally, Playwright also includes a playwright open <url> subcommand to
quickly launch the inspector on any URL. Examples in this post use playwright open <url>, but they also apply to UI mode and the inspector.
For convenience, Playwright provides a Docker image, which includes all
browsers pre-installed and configured so you can skip the dependency
installation steps. But what happens if you try to run Playwright with a headed
browser inside a Docker container – which normally doesn’t have a graphical
user interface?
# We expect a browser window to open and load google.comdocker run --rm mcr.microsoft.com/playwright npx -y playwright open google.com
Looks like you launched a headed browser without having a XServer running.
Set either 'headless: true' or use 'xvfb-run <your-playwright-app>' before running Playwright.
<3 Playwright Team
No browser window is launched! Instead we get an error message about not “having
a XServer running.” The definition and functionality of XServer are beyond the
scope of this article, but without it we can’t interact with applications that
require a user interface (like the browser). Here’s a more detailed
explanation if you want to learn more.
Searching for this error on the web will return results explaining how to
install and start XServer. That advice applies to non-containerized, Linux-based
systems. If your host system is macOS or Windows you actually don’t want to do
that. Instead we want the container to use the host XServer to launch
Playwright inside the container, which requires two modifications to our
docker command:
Set the DISPLAY environment variable inside the container using the -e
option
Mount the XServer Unix socket inside the container using the -v option
docker run --rm\-eDISPLAY=<host display>\-v /tmp/.X11-unix:/tmp/.X11-unix \
mcr.microsoft.com/playwright npx -y playwright open google.com
The value of <host display> will depend on your host operating system, and you
will need to ensure /tmp/.X11-unix is available for mounting. The following
sections explain how to do this for Windows and macOS.
You might find it surprising (I certainly did) that Microsoft Windows has a
native XServer even though it’s not a GNU/Linux system. It’s called WSLg, and
it’s included as part of the Windows Subsystem for Linux (WSL). You most
likely already have WSL and WSLg installed if you are running Docker Desktop
in recent builds of Windows 10 and 11.
Let’s start by verifying that WSL and WSLg are installed and running. First,
launch “WSL” from your Start Menu. A Linux terminal window should open (most
likely a recent version of Ubuntu). In that window, verify that the directory
/mnt/wslg/ exists and contains these files inside the Linux filesystem:
If you don’t see “WSL” in your Start Menu, or the ls command above fails with
No such file or directory, then your system is missing WSL entirely or is
running an old version. Visit the Microsoft Store to download an up-to-date
version.
Once you are all set up, we can set DISPLAY=:0 as explained in the official
guide:
docker run --rm\-eDISPLAY=:0 \-v /tmp/.X11-unix:/tmp/.X11-unix \
mcr.microsoft.com/playwright npx -y playwright open google.com
If all goes well, that should open two windows: a browser window with Google
loaded, and a Playwright Inspector window. Closing both will also stop the
container.
Apple’s operating system doesn’t include a built-in XServer, but we can use
XQuartz to provide one:
Install XQuartz: brew install --cask xquartz
Open XQuartz, go to Preferences -> Security, and check “Allow connections
from network clients”
Restart your computer (restarting XQuartz might not be enough)
Start XQuartz with xhost +localhost
Open Docker Desktop and edit settings to give access to /tmp/.X11-unix in
Preferences -> Resources -> File sharing
Once XQuartz is running with the right permissions, you can populate the
environment variable and socket:
docker run --rm\-eDISPLAY=host.docker.internal:0 \-v /tmp/.X11-unix:/tmp/.X11-unix \
mcr.microsoft.com/playwright npx -y playwright open google.com
If all goes well, that should open two windows: a browser window with Google
loaded, and a Playwright Inspector window. Closing both will also stop the
container.
services:web:image: mcr.microsoft.com/playwright
environment:-DISPLAY=...# Replace this line with the appropriate valuevolumes:- /tmp/.X11-unix:/tmp/.X11-unix
Remember: environment needs DISPLAY=:0 in Windows and
DISPLAY=host.docker.internal:0 in macOS. After editing and saving the file,
open the browser along with the Playwright Inspector with this command:
docker compose run --rm web npx -y playwright open google.com
Most likely you already have a Playwright test suite that you run in CI or
locally via Docker. Note that as long as you set the environment and volumes
keys on your service definition you will be able to run Playwright in headed
mode against your existing tests. Assuming you have a web service configured
to run your tests AND have configured the environment and volumes keys as
described above, you can drop into bash and run your tests graphically with:
docker compose run --rm web bash# If using the JS package
npx -y playwright test--ui# For other platforms (Python, etc.)PWDEBUG=1<command you use to run playwright>
This setup enables you to keep your dev and testing environment containerized
while providing the flexibility of a graphical interface when needed.
For many years, it has been ‘best practice’ to use relative units (especially em and rem) for sizing text. That’s great! But after playing around with my user preferences, I think we can improve on the common approaches.
It is frustrating to track down why an anchor isn’t being found. I’ve found a simple way that should work in most cases. If that doesn’t work, step through the checklist, and then dive in to get a better understanding of how Anchor Positioning works.