Difference between revisions of "Playwright"
(Make required edit for WebKit) |
(Bun + Playwright) |
||
| Line 131: | Line 131: | ||
} | } | ||
</syntaxHighlight> | </syntaxHighlight> | ||
| + | |||
| + | == Bun + Playwright == | ||
| + | |||
| + | Here is a <code>flake.nix</code> that is working with bun instead of nodejs (working today 2026-01-23). | ||
| + | Put <code>flake.nix</code>, <code>playwright.config.ts</code>, <code>package.json</code> and <code>tests/example.spec.ts</code> in the root directory of your project and run | ||
| + | * <code>nix develop</code> to install packages and enter the devShell | ||
| + | * <code>bun install</code> to download playwright dependencies to node_modules | ||
| + | * <code>bun --bun playwright test --headed</code> to test the setup | ||
| + | * <code>bun playwright test --headed</code> to verify that without <code>--bun</code> flag the nodejs version is run and bun library is not available. | ||
| + | |||
| + | ==== flake.nix ==== | ||
| + | |||
| + | <syntaxHighlight lang=nix> | ||
| + | { | ||
| + | description = "Bun + Playwright dev shell"; | ||
| + | |||
| + | inputs = { | ||
| + | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; | ||
| + | flake-utils.url = "github:numtide/flake-utils"; | ||
| + | }; | ||
| + | |||
| + | outputs = | ||
| + | { | ||
| + | self, | ||
| + | nixpkgs, | ||
| + | flake-utils, | ||
| + | ... | ||
| + | }: | ||
| + | flake-utils.lib.eachDefaultSystem ( | ||
| + | system: | ||
| + | let | ||
| + | pkgs = nixpkgs.legacyPackages.${system}; | ||
| + | pkgs-playwright = import nixpkgs { system = 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 | ||
| + | { | ||
| + | devShells.default = pkgs.mkShell { | ||
| + | buildInputs = with pkgs; [ | ||
| + | pkgs.bun | ||
| + | pkgs.playwright-driver.browsers | ||
| + | ]; | ||
| + | |||
| + | shellHook = '' | ||
| + | export PLAYWRIGHT_BROWSERS_PATH="${pkgs-playwright.playwright.browsers}"; | ||
| + | export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true; | ||
| + | export PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH="${pkgs-playwright.playwright.browsers}/chromium-${chromium-rev}/chrome-linux64/chrome"; | ||
| + | ''; | ||
| + | }; | ||
| + | } | ||
| + | ); | ||
| + | } | ||
| + | </syntaxHighlight> | ||
| + | |||
| + | ==== playwright.config.ts ==== | ||
| + | |||
| + | <syntaxHighlight lang=typescript> | ||
| + | import { defineConfig, devices } from '@playwright/test'; | ||
| + | |||
| + | export default defineConfig({ | ||
| + | projects: [ | ||
| + | { | ||
| + | name: 'chromium', | ||
| + | use: { | ||
| + | ...devices['Desktop Chrome'], | ||
| + | launchOptions: { | ||
| + | executablePath: process.env.PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH, | ||
| + | }, | ||
| + | }, | ||
| + | }, | ||
| + | ], | ||
| + | }); | ||
| + | </syntaxHighlight> | ||
| + | |||
| + | ==== package.json ==== | ||
| + | |||
| + | <syntaxHighlight lang=json> | ||
| + | { | ||
| + | "$schema": "https://json.schemastore.org/package.json", | ||
| + | "name": "playwright_with_bun", | ||
| + | "version": "1.0.0", | ||
| + | "description": "Playwright tests with Bun", | ||
| + | "scripts": { | ||
| + | "test": "playwright test" | ||
| + | }, | ||
| + | "dependencies": { | ||
| + | "@playwright/test": "^1.58.0", | ||
| + | "playwright-core": "^1.58.0" | ||
| + | }, | ||
| + | "devDependencies": { | ||
| + | "@types/bun": "^1.3.6" | ||
| + | } | ||
| + | } | ||
| + | </syntaxHighlight> | ||
| + | |||
| + | ==== tests/example.spec.ts ==== | ||
| + | |||
| + | <syntaxHighlight lang=typescript> | ||
| + | import { test, expect } from '@playwright/test'; | ||
| + | |||
| + | test('basic test', async ({ page }) => { | ||
| + | await page.goto('https://example.com'); | ||
| + | await expect(page).toHaveTitle(/Example/); | ||
| + | }); | ||
| + | |||
| + | test('Bun.stripANSI available', async () => { | ||
| + | expect(typeof Bun.stripANSI).toBe('function'); | ||
| + | }); | ||
| + | </syntaxHighlight> | ||
| + | |||
| + | ==== test output ==== | ||
| + | |||
| + | <syntaxHighlight lang="shell-session" style="color: inherit; background-color: #000;"> | ||
| + | |||
| + | [michi@nixos:~/dev/playwright_with_bun]$ bun --bun playwright test --headed | ||
| + | |||
| + | Running 2 tests using 1 worker | ||
| + | |||
| + | ✓ 1 [chromium] › tests/example.spec.ts:3:0 › basic test (1.1s) | ||
| + | ✓ 2 [chromium] › tests/example.spec.ts:8:0 › Bun.stripANSI available (3ms) | ||
| + | |||
| + | 2 passed (2.9s) | ||
| + | |||
| + | [michi@nixos:~/dev/playwright_with_bun]$ bun playwright test --headed | ||
| + | ReferenceError: Bun is not defined | ||
| + | at Object.<anonymous> (/home/michi/dev/playwright_with_bun/playwright.config.ts:10:27) | ||
| + | at Module._compile (node:internal/modules/cjs/loader:1706:14) | ||
| + | at Module.newCompile2 (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/third_party/pirates.js:46:29) | ||
| + | at Object.<anonymous> (node:internal/modules/cjs/loader:1839:10) | ||
| + | at Object.newLoader2 [as .ts] (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/third_party/pirates.js:52:22) | ||
| + | at Module.load (node:internal/modules/cjs/loader:1441:32) | ||
| + | at Function._load (node:internal/modules/cjs/loader:1263:12) | ||
| + | at TracingChannel.traceSync (node:diagnostics_channel:328:14) | ||
| + | at wrapModuleLoad (node:internal/modules/cjs/loader:237:24) | ||
| + | at Module.require (node:internal/modules/cjs/loader:1463:12) | ||
| + | at require (node:internal/modules/helpers:147:16) | ||
| + | at requireOrImport (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/transform/transform.js:225:18) | ||
| + | at loadUserConfig (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/common/configLoader.js:107:89) | ||
| + | at loadConfig (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/common/configLoader.js:119:28) | ||
| + | at loadConfigFromFile (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/common/configLoader.js:331:10) | ||
| + | at runTests (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/program.js:197:18) | ||
| + | at i.<anonymous> (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/program.js:70:7) | ||
| + | error: "playwright" exited with code 1 | ||
| + | </syntaxHighlight> | ||
| + | |||
| + | === big hint === | ||
| + | VSCode plugin playwright currently does not support bun. Stick to nodejs for now if you are a GUI guy. | ||
Revision as of 22:17, 23 January 2026
Installing browsers for playwright under NixOS
Normally, at first run, playwright will tell you to run playwright install. The purpose of this is to install browsers for you that it can then use for testing. The installation itself will technically work. Unfortunately, the installed browsers will not be suitable to be used inside NixOS. This is due to the fact that dependencies will not be at places where the browsers expect them to be. To mitigate this problem, nixpkgs has a package called playwright-driver.browsers. Before you start your script, make sure to set
export PLAYWRIGHT_BROWSERS_PATH=/path/to/drivers
You can for example put this shell.nix in the directory with your playwright tests:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = with pkgs; [
vscode
playwright-driver.browsers
];
shellHook = ''
export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers}
export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true
export PLAYWRIGHT_HOST_PLATFORM_OVERRIDE="ubuntu-24.04"
'';
}
You can then just run nix-shell --run "code ." to open Visual Studio Code in that directory.
Don't forget to install the Playwright Test for VSCode extension in Visual Studio Code.
Then you should be able to run your tests in Visual Studio Code.
Using Devenv
With Devenv you can also set certain environment variables and pin packages to make playwright work.
Again, make sure to pin to the same version of playwright in devenv.yaml and package.json!
devenv.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
{
# https://devenv.sh/basics/
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";
};
# https://devenv.sh/packages/
packages = with pkgs; [
just
nodejs
];
# https://devenv.sh/languages/
languages.javascript.enable = true;
dotenv.disableHint = true;
cachix.enable = false;
# https://devenv.sh/scripts/
scripts.intro.exec = ''
playwrightNpmVersion="$(npm show @playwright/test version)"
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! Please adapt the configuration."
else
echo "✅ Playwright versions in nix and npm are the same"
fi
echo
env | grep ^PLAYWRIGHT
'';
enterShell = ''
intro
'';
# See full reference at https://devenv.sh/reference/options/
}
devenv.yaml
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
inputs:
nixpkgs:
url: github:NixOS/nixpkgs/nixos-unstable
# Currently pinned to: playwright@1.52.0
# See https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=playwright
nixpkgs-playwright:
url: github:NixOS/nixpkgs/979daf34c8cacebcd917d540070b52a3c2b9b16e
package.json
{
"name": "e2e-tests-ng",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@playwright/test": "1.52.0",
"eslint": "^8.41.0"
},
"engines": {
"node": ">=18.0.0"
},
"scripts": {
"playwright:test": "playwright test",
"playwright:test:ui": "playwright test --ui",
"playwright:install": "playwright install",
"lint": "eslint ."
},
"dependencies": {
"dotenv": "^16.0.3",
"jsrsasign": "^11.0.0"
}
}
Bun + Playwright
Here is a flake.nix that is working with bun instead of nodejs (working today 2026-01-23).
Put flake.nix, playwright.config.ts, package.json and tests/example.spec.ts in the root directory of your project and run
nix developto install packages and enter the devShellbun installto download playwright dependencies to node_modulesbun --bun playwright test --headedto test the setupbun playwright test --headedto verify that without--bunflag the nodejs version is run and bun library is not available.
flake.nix
{
description = "Bun + Playwright dev shell";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
pkgs-playwright = import nixpkgs { system = 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
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
pkgs.bun
pkgs.playwright-driver.browsers
];
shellHook = ''
export PLAYWRIGHT_BROWSERS_PATH="${pkgs-playwright.playwright.browsers}";
export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true;
export PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH="${pkgs-playwright.playwright.browsers}/chromium-${chromium-rev}/chrome-linux64/chrome";
'';
};
}
);
}
playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
launchOptions: {
executablePath: process.env.PLAYWRIGHT_LAUNCH_OPTIONS_EXECUTABLE_PATH,
},
},
},
],
});
package.json
{
"$schema": "https://json.schemastore.org/package.json",
"name": "playwright_with_bun",
"version": "1.0.0",
"description": "Playwright tests with Bun",
"scripts": {
"test": "playwright test"
},
"dependencies": {
"@playwright/test": "^1.58.0",
"playwright-core": "^1.58.0"
},
"devDependencies": {
"@types/bun": "^1.3.6"
}
}
tests/example.spec.ts
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example/);
});
test('Bun.stripANSI available', async () => {
expect(typeof Bun.stripANSI).toBe('function');
});
test output
[michi@nixos:~/dev/playwright_with_bun]$ bun --bun playwright test --headed
Running 2 tests using 1 worker
✓ 1 [chromium] › tests/example.spec.ts:3:0 › basic test (1.1s)
✓ 2 [chromium] › tests/example.spec.ts:8:0 › Bun.stripANSI available (3ms)
2 passed (2.9s)
[michi@nixos:~/dev/playwright_with_bun]$ bun playwright test --headed
ReferenceError: Bun is not defined
at Object.<anonymous> (/home/michi/dev/playwright_with_bun/playwright.config.ts:10:27)
at Module._compile (node:internal/modules/cjs/loader:1706:14)
at Module.newCompile2 (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/third_party/pirates.js:46:29)
at Object.<anonymous> (node:internal/modules/cjs/loader:1839:10)
at Object.newLoader2 [as .ts] (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/third_party/pirates.js:52:22)
at Module.load (node:internal/modules/cjs/loader:1441:32)
at Function._load (node:internal/modules/cjs/loader:1263:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:237:24)
at Module.require (node:internal/modules/cjs/loader:1463:12)
at require (node:internal/modules/helpers:147:16)
at requireOrImport (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/transform/transform.js:225:18)
at loadUserConfig (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/common/configLoader.js:107:89)
at loadConfig (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/common/configLoader.js:119:28)
at loadConfigFromFile (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/common/configLoader.js:331:10)
at runTests (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/program.js:197:18)
at i.<anonymous> (/home/michi/dev/playwright_with_bun/node_modules/playwright/lib/program.js:70:7)
error: "playwright" exited with code 1
big hint
VSCode plugin playwright currently does not support bun. Stick to nodejs for now if you are a GUI guy.