Playwright: Difference between revisions
imported>Pbek m Fix typos |
Ryuheechul (talk | contribs) Add a new way to use playwright with NixOS that employees a container runtime |
||
(5 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
== Installing browsers for playwright under NixOS == | == Installing browsers for playwright under NixOS == | ||
Normally, at first run, playwright will tell you to run <code>playwright install</code>. 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 <code>playwright-driver.browsers</code>. Before you start your script, make sure to set | |||
Normally, at first run, [https://playwright.dev/ playwright] will tell you to run <code>playwright install</code>. 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 <code>playwright-driver.browsers</code>. Before you start your script, make sure to set | |||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
export PLAYWRIGHT_BROWSERS_PATH=/path/to/drivers | export PLAYWRIGHT_BROWSERS_PATH=/path/to/drivers | ||
</syntaxHighlight> | </syntaxHighlight> | ||
You can for example put this <code>shell.nix</code> in the directory with your playwright | You can for example put this <code>shell.nix</code> in the directory with your playwright-related code: | ||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
{ pkgs ? import <nixpkgs> {} }: | { pkgs ? import <nixpkgs> {} }: | ||
pkgs.mkShell { | pkgs.mkShell { | ||
nativeBuildInputs = | nativeBuildInputs = [ | ||
pkgs.playwright-driver.browsers | |||
]; | ]; | ||
Line 22: | Line 22: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
== Playwright with Visual Studio Code == | |||
If you are using playwright with [https://wiki.nixos.org/wiki/Visual_Studio_Code Visual Studio Code], you may want to add <code>vscode</code> to the package list shown earlier. With Visual Studio Code installed you can run <code>nix-shell --run "code ."</code> to open your playwright-related directory. | |||
Don't forget to install the <code>Playwright Test for VSCode</code> extension in Visual Studio Code. | Don't forget to install the <code>Playwright Test for VSCode</code> extension in Visual Studio Code. | ||
Line 28: | Line 30: | ||
Then you should be able to run your tests in Visual Studio Code. | Then you should be able to run your tests in Visual Studio Code. | ||
{{Note|Keep in mind that you need to use the same version of playwright in your node playwright project as in your nixpkgs!}} | {{Note|Keep in mind that you need to use the same version of playwright in your node playwright project as in your nixpkgs, or else playwright will try to use browsers versions that aren't installed!}} | ||
== Playwright with Devenv == | |||
With [https://devenv.sh/ 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 <code>devenv.yaml</code> and <code>package.json</code>! | |||
=== devenv.nix === | |||
<syntaxhighlight lang="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 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! 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/ | |||
} | |||
</syntaxhighlight> | |||
=== devenv.yaml === | |||
<syntaxHighlight lang=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 | |||
</syntaxHighlight> | |||
=== package.json === | |||
<syntaxHighlight lang=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" | |||
} | |||
} | |||
</syntaxHighlight> | |||
== Playwright via Docker == | |||
https://playwright.dev/docs/docker#remote-connection can be a good option to make use of a container (instead of wrestling with NixOS) to run browsers.<syntaxhighlight lang="nix"># devenv.nix example that simplifies the configuration | |||
# but it's easy to setup the env var and run the command manually without devenv too | |||
{ | |||
env.PW_TEST_CONNECT_WS_ENDPOINT = "ws://127.0.0.1:3000/"; | |||
# run it with `devenv processes up` and in another terminal run `npm exec playwright test` | |||
processes.pw-remote.exec = "docker run -p 3000:3000 --rm --init --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.52.0-noble /bin/sh -c 'npx -y playwright@1.52.0 run-server --port 3000 --host 0.0.0.0'"; | |||
}</syntaxhighlight>Will need a slight tweak like below for the IP address due to a small limitation comes with the container use.<syntaxhighlight lang="typescript"> | |||
// example.spec.ts | |||
import { test, expect } from '@playwright/test'; | |||
test('has title', async ({ page }) => { | |||
// await page.goto('http://localhost:3333/'); // can't do due to the browsers running within a container but your server is running on the host | |||
await page.goto('http://host.docker.internal:3333/'); // so do this instead | |||
// also make sure your server code runs for playwright, too - https://playwright.dev/docs/test-webserver#configuring-a-web-server | |||
await expect(page).toHaveTitle(/your website/); | |||
}); | |||
</syntaxhighlight> | |||
[[Category:Development]] |
Latest revision as of 05:53, 28 May 2025
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-related code:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
nativeBuildInputs = [
pkgs.playwright-driver.browsers
];
shellHook = ''
export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers}
export PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=true
'';
}
Playwright with Visual Studio Code
If you are using playwright with Visual Studio Code, you may want to add vscode
to the package list shown earlier. With Visual Studio Code installed you can run nix-shell --run "code ."
to open your playwright-related 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.
Playwright with 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 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! 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"
}
}
Playwright via Docker
https://playwright.dev/docs/docker#remote-connection can be a good option to make use of a container (instead of wrestling with NixOS) to run browsers.
# devenv.nix example that simplifies the configuration
# but it's easy to setup the env var and run the command manually without devenv too
{
env.PW_TEST_CONNECT_WS_ENDPOINT = "ws://127.0.0.1:3000/";
# run it with `devenv processes up` and in another terminal run `npm exec playwright test`
processes.pw-remote.exec = "docker run -p 3000:3000 --rm --init --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v1.52.0-noble /bin/sh -c 'npx -y playwright@1.52.0 run-server --port 3000 --host 0.0.0.0'";
}
Will need a slight tweak like below for the IP address due to a small limitation comes with the container use.
// example.spec.ts
import { test, expect } from '@playwright/test';
test('has title', async ({ page }) => {
// await page.goto('http://localhost:3333/'); // can't do due to the browsers running within a container but your server is running on the host
await page.goto('http://host.docker.internal:3333/'); // so do this instead
// also make sure your server code runs for playwright, too - https://playwright.dev/docs/test-webserver#configuring-a-web-server
await expect(page).toHaveTitle(/your website/);
});