Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/playwright/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Requirements

Select the node feature alongside this one. The install uses `npm` and exits with an explicit error
when it cannot find it — it never installs node for you, so your own version pin stays intact.

```json
"features": {
"ghcr.io/devcontainers/features/node:2": {},
"ghcr.io/orianna-ai/devcontainer-features/playwright:1": {}
}
```

Debian and Ubuntu only. Playwright installs Chromium's shared libraries with apt and has no
equivalent for other package managers.

## Browsers

Chromium only, plus the headless shell and ffmpeg that come with it. Firefox and WebKit are not
downloaded.

They live in `/usr/local/share/ms-playwright` rather than Playwright's default `$HOME/.cache`, and
`PLAYWRIGHT_BROWSERS_PATH` is set through `containerEnv` to match. Nothing to configure, and it
keeps working when `HOME` is replaced at run time.
47 changes: 47 additions & 0 deletions src/playwright/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

# Playwright (playwright)

Installs the Playwright CLI and Chromium. Requires the node feature.

## Example Usage

```json
"features": {
"ghcr.io/orianna-ai/devcontainer-features/playwright:1": {}
}
```

## Options

| Options Id | Description | Type | Default Value |
|-----|-----|-----|-----|
| version | Version of the @playwright/cli package to install. | string | latest |

## Requirements

Select the node feature alongside this one. The install uses `npm` and exits with an explicit error
when it cannot find it — it never installs node for you, so your own version pin stays intact.

```json
"features": {
"ghcr.io/devcontainers/features/node:2": {},
"ghcr.io/orianna-ai/devcontainer-features/playwright:1": {}
}
```

Debian and Ubuntu only. Playwright installs Chromium's shared libraries with apt and has no
equivalent for other package managers.

## Browsers

Chromium only, plus the headless shell and ffmpeg that come with it. Firefox and WebKit are not
downloaded.

They live in `/usr/local/share/ms-playwright` rather than Playwright's default `$HOME/.cache`, and
`PLAYWRIGHT_BROWSERS_PATH` is set through `containerEnv` to match. Nothing to configure, and it
keeps working when `HOME` is replaced at run time.


---

_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._
20 changes: 20 additions & 0 deletions src/playwright/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"containerEnv": {
"PLAYWRIGHT_BROWSERS_PATH": "/usr/local/share/ms-playwright"
},
"description": "Installs the Playwright CLI and Chromium. Requires the node feature.",
"id": "playwright",
"installsAfter": [
"ghcr.io/devcontainers/features/common-utils",
"ghcr.io/devcontainers/features/node"

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declining dependsOn — it would break the consumer this feature exists for, so I documented the requirement instead.

The spec deduplicates Features only when the id and the options match exactly ("two Features are identical if their manifest digests are equal, and the options executed against the Feature are equal"). orianna-ai/devcontainer already selects ghcr.io/devcontainers/features/node:2 with {"version": "24.18.0"}. A dependsOn entry has to name some tag and some options, and whatever I pick will not match that, so both copies install and whichever runs last wins the nvm default alias — silently unpinning a node version renovate manages. Hardcoding node:2 + 24.18.0 into a shared feature to dodge that is worse.

The other suggestion, having the installer provision node itself, reimplements the node feature inside this one and hits the same collision.

So: NOTES.md now gives the README a Requirements section showing node selected alongside playwright, and the installer keeps failing fast with npm was not found; this feature has to install after the node feature. The documented setup is the two-feature one; the single-feature example above it is generated from the manifest and I cannot edit it.


Generated by Claude Code

],
Comment thread
greptile-apps[bot] marked this conversation as resolved.
"name": "Playwright",
"options": {
"version": {
"default": "latest",
"description": "Version of the @playwright/cli package to install.",
"type": "string"
}
},
"version": "1.0.0"
}
48 changes: 48 additions & 0 deletions src/playwright/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash
set -euo pipefail

VERSION="${VERSION:-latest}"
BROWSERS_PATH="/usr/local/share/ms-playwright"

export DEBIAN_FRONTEND=noninteractive
export PLAYWRIGHT_BROWSERS_PATH="${BROWSERS_PATH}"

if ! command -v apt-get >/dev/null 2>&1; then
echo "apt-get was not found; this feature only supports debian and ubuntu base images" >&2
exit 1
fi

if ! command -v npm >/dev/null 2>&1; then
export NVM_DIR="${NVM_DIR:-/usr/local/share/nvm}"

# shellcheck source=/dev/null
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
fi

if ! command -v npm >/dev/null 2>&1; then
echo "npm was not found; this feature has to install after the node feature" >&2
exit 1
fi

npm_root="$(npm root -g)"
owner="$(stat -c '%u:%g' "${npm_root}")"

npm install --global "@playwright/cli@${VERSION}"

playwright_core="$(find "${npm_root}" -maxdepth 6 -path '*/playwright-core/cli.js' -print -quit)"

if [ -z "${playwright_core}" ]; then
echo "playwright-core was not found under ${npm_root}" >&2
exit 1
fi

apt-get update -y
Comment thread
greptile-apps[bot] marked this conversation as resolved.

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took the second option — an explicit supported-distribution check. Playwright only knows how to install Chromium's shared libraries with apt, so there is no Fedora/RHEL branch to implement; the feature is inherently Debian and Ubuntu only.

install.sh now checks for apt-get before the npm install, so a non-Debian build stops in a second with apt-get was not found; this feature only supports debian and ubuntu base images instead of after a package download. NOTES.md documents the constraint and it shows up in the generated README.

Not adding the non-Ubuntu scenario: devcontainer features test scenarios assert that a build succeeds and the checks pass, so there is no way to express "this build should fail" — the scenario would just be a red job.


Generated by Claude Code


node "${playwright_core}" install-deps chromium
node "${playwright_core}" install chromium

rm -rf /var/lib/apt/lists/*
npm cache clean --force

chown -R "${owner}" "${npm_root}" "$(npm prefix -g)/bin" "${BROWSERS_PATH}"
chmod -R a+rX "${BROWSERS_PATH}"
13 changes: 13 additions & 0 deletions test/playwright/scenarios.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"ubuntu": {
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {},
"ghcr.io/devcontainers/features/node:1": {},
"playwright": {
"version": "latest"
}
},
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04",
"user": "vscode"
}
}
11 changes: 11 additions & 0 deletions test/playwright/ubuntu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash
set -e

# shellcheck source=/dev/null
source \
dev-container-features-test-lib
check 'check if playwright-cli exists' bash -c "command -v playwright-cli"
check 'check if the browsers path is exported' bash -c "test \"${PLAYWRIGHT_BROWSERS_PATH:-}\" = /usr/local/share/ms-playwright"
check 'check if chromium was downloaded' bash -c "ls /usr/local/share/ms-playwright | grep -q chromium"
check 'check if the browsers are readable by the remote user' bash -c "test -r /usr/local/share/ms-playwright && test -x /usr/local/share/ms-playwright"
reportResults
Loading