playwright-devenv
Skill1 starsChanged 6 months agoMITView on GitHub
Set up Playwright browser automation in devenv.sh on NixOS, including browser installation, version pinning, and troubleshooting.
- Reads credentials
- Installs packages
We split this skill into the rules it gives an agent
22 rules. About 0 are common, 10 are distinctive, and 12 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈10
Distinctive · estimate
This author's own choices. Worth a look.
12
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 10
Use this skill when setting up Playwright browser automation in a devenv.sh project on NixOS.
- Very specific: line 23
Solution: Use nixpkgs' playwright-driver.browsers package and set environment variables to tell Playwright where to find the Nix-provided …
- Distinctive: line 131
Use the exact same version as in your pinned nixpkgs:
- Very specific: line 203
Check versions: the intro script shows both
- Very specific: line 204
Update devenv.yaml nixpkgs-playwright commit to match npm version
- Very specific: line 205
Run devenv update to update lock file
- Very specific: line 212
Fix: Ensure env var is set in devenv.nix (see Step 3 above).
- Very specific: line 218
Fix: Verify PLAYWRIGHT_BROWSERS_PATH points to Nix store path:
- Distinctive: line 229
Use the Docker remote approach (works anywhere)
- Distinctive: line 231
Use Playwright's official Docker images in CI
- Distinctive: line 235
Cause: All browsers installed by default (Chromium + Firefox + WebKit ≈ 1GB).
- Distinctive: line 237
Fix: Use selective browser installation (see "Selective Browser Installation" above).
- Very specific: line 244
Update devenv.yaml nixpkgs-playwright URL with new commit
- Very specific: line 245
Run devenv update to update lock
- Very specific: line 247
Verify versions match: the intro script will confirm
- Distinctive: line 293
Run tests as a long-running process during development:
- Distinctive: line 307
Run tests as a cacheable task:
- Distinctive: line 322
Run Playwright tests on pre-push:
- Very specific: line 423
ALWAYS pin the nixpkgs-playwright input: - don't use nixos-unstable directly, pin to a specific commit for reproducibility.
- Distinctive: line 427
Test the setup with a simple test: before writing complex test suites.
- Very specific: line 432
Forgetting to update
devenv.lock: After changing devenv.yaml, run devenv update and restart shell. - Distinctive: line 436
Disk space: All three browsers consume ~1GB - use selective installation if space-constrained.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Playwright with devenv.sh - NixOS Setup
Use this skill when setting up Playwright browser automation in a devenv.sh project on NixOS. This handles browser installation, version pinning, environment configuration, and common troubleshooting.
When to Use
- Adding Playwright to a project that uses devenv.sh on NixOS
- Resolving browser launch failures caused by missing Nix store library paths
- Pinning or updating Playwright versions in both
devenv.yamlandpackage.json - Configuring CI to run Playwright tests inside a Nix environment
The Problem with Playwright on NixOS
Playwright's default playwright install command downloads browsers that expect dependencies in standard Linux paths. NixOS stores dependencies in unique /nix/store/ paths, causing browsers to fail with missing library errors.
Solution: Use nixpkgs' playwright-driver.browsers package and set environment variables to tell Playwright where to find the Nix-provided browsers.
Critical Rule: Version Synchronization
MANDATORY: Playwright versions in devenv.yaml (nixpkgs input) and package.json MUST match exactly, or browsers won't work.
Nix: playwright@1.52.0
npm: @playwright/test@1.52.0
✅ Versions match - browsers work
Nix: playwright@1.52.0
npm: @playwright/test@1.48.0
❌ Version mismatch - browsers failQuick Start Configuration
Step 1: Find the Right Playwright Version
Visit NixOS Package Search to find:
- Latest available Playwright version
- The nixpkgs commit hash for that version
Example:
Package: playwright-driver 1.52.0
Channel: nixos-unstable
Commit: 979daf34c8cacebcd917d540070b52a3c2b9b16eStep 2: Configure devenv.yaml
Pin the nixpkgs-playwright input to the exact commit from Step 1:
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixos-unstable
# Pin to specific Playwright version commit
# Update commit hash from: https://search.nixos.org/packages?channel=unstable&query=playwright
nixpkgs-playwright:
url: github:NixOS/nixpkgs/979daf34c8cacebcd917d540070b52a3c2b9b16eStep 3: Configure devenv.nix
{ pkgs, lib, config, inputs, ... }:
let
# Import the pinned playwright nixpkgs
pkgs-playwright = import inputs.nixpkgs-playwright {
system = pkgs.stdenv.system;
};
# Extract chromium revision for executable path
browsers = (builtins.fromJSON (builtins.readFile "${pkgs-playwright.playwright-driver}/browsers.json")).browsers;
chromium-rev = (builtins.head (builtins.filter (x: x.name == "chromium") browsers)).revision;
in
{
# Environment variables for Playwright
env = {
PLAYWRIGHT_BROWSERS_PATH = "${pkgs-playwright.playwright.browsers}";
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
PLAYWRIGHT_NODEJS_PATH = "${pkgs.nodejs}/bin/node";
PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH = "${pkgs-playwright.playwright.browsers}/chromium-${chromium-rev}/chrome-linux/chrome";
};
# Add Node.js and other required packages
packages = with pkgs; [
nodejs
];
# Enable JavaScript language support
languages.javascript.enable = true;
# Optional: Add npm/pnpm auto-install
# languages.javascript.pnpm.enable = true;
# languages.javascript.pnpm.install.enable = true;
# Optional: Startup message to verify versions
scripts.intro.exec = ''
playwrightNpmVersion="$(npm view ./. devDependencies'[@playwright/test]')"
echo "❄️ Playwright nix version: ${pkgs-playwright.playwright.version}"
echo "📦 Playwright npm version: $playwrightNpmVersion"
if [ "${pkgs-playwright.playwright.version}" != "$playwrightNpmVersion" ]; then
echo "❌ Playwright versions in nix (in devenv.yaml) and npm (in package.json) are not the same!"
echo " Update devenv.yaml nixpkgs-playwright commit to match package.json version."
else
echo "✅ Playwright versions in nix and npm are the same"
fi
echo
env | grep ^PLAYWRIGHT
'';
enterShell = ''
intro
'';
}Step 4: Configure package.json
Use the exact same version as in your pinned nixpkgs:
{
"name": "e2e-tests",
"version": "1.0.0",
"devDependencies": {
"@playwright/test": "1.52.0"
},
"scripts": {
"test": "playwright test",
"test:ui": "playwright test --ui",
"test:headed": "playwright test --headed"
}
}Step 5: Install and Verify
# Enter devenv shell
devenv shell
# Install dependencies
npm install # or pnpm install
# Verify setup (should show matching versions)
# The intro script will automatically run and show version comparison
# Run tests
npm run testEnvironment Variables Reference
| Variable | Purpose | Required |
PLAYWRIGHT_BROWSERS_PATH | Path to Nix-provided browser binaries | Yes |
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS | Skip Playwright's host validation (NixOS has different paths) | Yes |
PLAYWRIGHT_NODEJS_PATH | Path to Node.js binary (for Playwright server) | Recommended |
PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH | Direct path to browser executable (Chromium) | Optional |
Advanced Configurations
Multiple Browser Support
By default, the configuration uses Chromium. To support Firefox, WebKit, or all browsers:
{
env = {
PLAYWRIGHT_BROWSERS_PATH = "${pkgs-playwright.playwright.browsers}";
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
# Firefox
# PLAYWRIGHT_FIREFOX_EXECUTABLE_PATH = "${pkgs-playwright.playwright.browsers}/firefox-${firefox-rev}/firefox/firefox";
# WebKit
# PLAYWRIGHT_WEBKIT_EXECUTABLE_PATH = "${pkgs-playwright.playwright.browsers}/webkit-${webkit-rev}/...";
};
}Extract revisions from browsers.json the same way as chromium-rev in the base config.
Troubleshooting
Error: "Executable doesn't exist at ..."
Cause: Version mismatch between nix and npm.
Fix:
- Check versions: the
introscript shows both - Update
devenv.yamlnixpkgs-playwright commit to match npm version - Run
devenv updateto update lock file - Exit and re-enter shell:
exitthendevenv shell
Error: "browserType.launch: Host system is missing dependencies"
Cause: PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS not set.
Fix: Ensure env var is set in devenv.nix (see Step 3 above).
Error: "Failed to launch browser ... cannot open shared object file"
Cause: Browser trying to use system libraries instead of Nix libraries.
Fix: Verify PLAYWRIGHT_BROWSERS_PATH points to Nix store path:
echo $PLAYWRIGHT_BROWSERS_PATH
# Should output: /nix/store/...-playwright-browsers/...Tests pass locally but fail in CI
Cause: CI environment may not have the same Nix setup.
Fix Options:
- Use the Docker remote approach (works anywhere)
- Set up Nix in CI with cachix for binary caching
- Use Playwright's official Docker images in CI
Browsers take up too much disk space
Cause: All browsers installed by default (Chromium + Firefox + WebKit ≈ 1GB).
Fix: Use selective browser installation (see "Selective Browser Installation" above).
Updating Playwright Version
Process:
- Update
package.json:"@playwright/test": "1.53.0" - Find new nixpkgs commit: search.nixos.org
- Update
devenv.yamlnixpkgs-playwright URL with new commit - Run
devenv updateto update lock - Exit shell and re-enter:
exitthendevenv shell - Verify versions match: the
introscript will confirm
Testing the Setup
Create tests/example.spec.ts:
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});Create playwright.config.ts:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
trace: 'on-first-retry',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
});Run:
npm run testIntegration with devenv Processes
Run tests as a long-running process during development:
{
processes.playwright-watch = {
exec = "playwright test --ui";
};
}Start: devenv up
Integration with devenv Tasks
Run tests as a cacheable task:
{
tasks."test:e2e" = {
exec = "playwright test";
before = [ "devenv:enterShell" ];
};
}Run: devenv tasks run test:e2e
Integration with Git Hooks
Run Playwright tests on pre-push:
{
git-hooks.hooks = {
playwright-test = {
enable = true;
name = "playwright";
entry = "npm run test";
language = "system";
stages = [ "pre-push" ];
};
};
}Complete Working Example
Minimal working setup:
Directory structure:
.
├── devenv.nix
├── devenv.yaml
├── package.json
├── playwright.config.ts
└── tests/
└── example.spec.tsdevenv.yaml:
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixos-unstable
nixpkgs-playwright:
url: github:NixOS/nixpkgs/979daf34c8cacebcd917d540070b52a3c2b9b16edevenv.nix:
{ pkgs, lib, config, inputs, ... }:
let
pkgs-playwright = import inputs.nixpkgs-playwright { system = pkgs.stdenv.system; };
browsers = (builtins.fromJSON (builtins.readFile "${pkgs-playwright.playwright-driver}/browsers.json")).browsers;
chromium-rev = (builtins.head (builtins.filter (x: x.name == "chromium") browsers)).revision;
in
{
env = {
PLAYWRIGHT_BROWSERS_PATH = "${pkgs-playwright.playwright.browsers}";
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = true;
PLAYWRIGHT_NODEJS_PATH = "${pkgs.nodejs}/bin/node";
PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH = "${pkgs-playwright.playwright.browsers}/chromium-${chromium-rev}/chrome-linux/chrome";
};
packages = [ pkgs.nodejs ];
languages.javascript.enable = true;
}package.json:
{
"devDependencies": {
"@playwright/test": "1.52.0"
},
"scripts": {
"test": "playwright test"
}
}playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({ testDir: './tests' });tests/example.spec.ts:
import { test, expect } from '@playwright/test';
test('basic', async ({ page }) => {
await page.goto('https://playwright.dev/');
await expect(page).toHaveTitle(/Playwright/);
});Run:
devenv shell
npm install
npm run testRules
- ALWAYS verify Playwright version match between
devenv.yaml(nixpkgs commit) andpackage.jsonbefore troubleshooting other issues. - NEVER run
playwright install- it downloads incompatible binaries. Useplaywright-driver.browsersfrom nixpkgs. - ALWAYS set
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true- Playwright's host checks don't understand NixOS paths. - ALWAYS pin the nixpkgs-playwright input - don't use
nixos-unstabledirectly, pin to a specific commit for reproducibility. - Use the
introscript pattern to verify version synchronization on every shell entry. - When updating Playwright, update BOTH
devenv.yamlcommit hash ANDpackage.jsonversion together. - For CI/CD, prefer the Docker remote browser approach for consistency across environments.
- Test the setup with a simple test before writing complex test suites.
- Check
$PLAYWRIGHT_BROWSERS_PATHfirst when debugging browser launch issues.
Common Pitfalls
- Forgetting to update
devenv.lock: After changingdevenv.yaml, rundevenv updateand restart shell. - Version drift: npm/pnpm updating
@playwright/testwithout updating nix config. - Missing Node.js: Playwright requires Node.js - ensure it's in
packagesor vialanguages.javascript.enable = true. - CI failures: CI doesn't inherit devenv shell - either setup Nix in CI or use Docker approach.
- Disk space: All three browsers consume ~1GB - use selective installation if space-constrained.
References
Inputs
devenv.nixanddevenv.yamlfor the project- Desired Playwright version (must match in both Nix and npm)
- Target browsers (chromium, firefox, webkit)
Outputs
- Updated
devenv.nixwithplaywright-driver.browserspackage and required env vars (PLAYWRIGHT_BROWSERS_PATH,PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS) devenv.yamlwith the correct nixpkgs revision for the matching Playwright version
Examples
# devenv.nix — Playwright on NixOS
{ pkgs, ... }: {
packages = [ pkgs.playwright-driver.browsers ];
env = {
PLAYWRIGHT_BROWSERS_PATH = "${pkgs.playwright-driver.browsers}";
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS = "true";
};
}In this repository36 other files it gives its agents.
- skills/backend-best-practices/AGENTS.mdAGENTS.md
- adr-writerSkill
- application-healthchecksSkill
- backend-best-practicesSkill
- bspec-prd-discoverySkill
- bspec-story-implementationSkill
- bspec-story-reviewSkill
- bspec-story-syncSkill
- bspec-technical-architectureSkill
- bspec-workflowSkill
- conventional-commitsSkill
- copier-scaffoldSkill
- devenvSkill
- direnvSkill
- docker-composeSkill
- dockerfileSkill
- docker-setupSkill
- docs-writerSkill
- github-actions-dockerSkill
- gitleaks-setupSkill
- golang-developmentSkill
- golang-slogSkill
- golang-testingSkill
- project-webappSkill
- readme-writerSkill
- release-drafter-setupSkill
- release-drafterSkill
- release-notesSkill
- renovate-pr-triageSkill
- renovate-setupSkill
- structured-loggingSkill
- summarize-articleSkill
- summarize-youtube-videoSkill
- tailwind-v4Skill
- vicinae-extensionsSkill
- zensical-setupSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

