playwright: 1.57.0 -> 1.58.2

This commit is contained in:
Konstantin Alekseev
2026-03-08 17:53:58 +02:00
committed by Gaetan Lepage
parent cf5966c180
commit 9cded17205
13 changed files with 415 additions and 185 deletions
+6 -4
View File
@@ -18,11 +18,13 @@ buildNpmPackage rec {
npmDepsHash = "sha256-Qsln4llNpfXYXhSEfHnvdsFIF7adHKEyC1eGHtVY2Qk=";
# Codex MCP smoke test (after `codex mcp add playwright-nix --env DISPLAY=:0 -- $out/bin/mcp-server-playwright --headless --isolated`):
# timeout 45s codex exec --dangerously-bypass-approvals-and-sandbox --skip-git-repo-check "Use only playwright-nix MCP tools. Navigate to https://example.com and return only the page title."
postInstall = ''
rm -r $out/lib/node_modules/@playwright/mcp/node_modules/playwright
rm -r $out/lib/node_modules/@playwright/mcp/node_modules/playwright-core
ln -s ${playwright-test}/lib/node_modules/playwright $out/lib/node_modules/@playwright/mcp/node_modules/playwright
ln -s ${playwright-test}/lib/node_modules/playwright-core $out/lib/node_modules/@playwright/mcp/node_modules/playwright-core
rm -rf "$out/lib/node_modules/@playwright/mcp/node_modules/playwright"
rm -rf "$out/lib/node_modules/@playwright/mcp/node_modules/playwright-core"
ln -s ${playwright-test}/lib/node_modules/playwright "$out/lib/node_modules/@playwright/mcp/node_modules/playwright"
ln -s ${playwright-test}/lib/node_modules/playwright-core "$out/lib/node_modules/@playwright/mcp/node_modules/playwright-core"
wrapProgram $out/bin/mcp-server-playwright \
--set PLAYWRIGHT_BROWSERS_PATH ${playwright-driver.browsers} \
@@ -7,6 +7,7 @@
fetchFromGitHub,
pyee,
python,
pythonOlder,
setuptools,
setuptools-scm,
playwright-driver,
@@ -20,14 +21,15 @@ in
buildPythonPackage rec {
pname = "playwright";
# run ./pkgs/development/web/playwright/update.sh to update
version = "1.57.0";
version = "1.58.0";
pyproject = true;
disabled = pythonOlder "3.9";
src = fetchFromGitHub {
owner = "microsoft";
repo = "playwright-python";
tag = "v${version}";
hash = "sha256-LXTMVC6ytjo7l0QDkNPxtoMTYjmYMjCVqHz61BgAn6A=";
hash = "sha256-gK19pjB8TDy/kK+fb4pjwlGZlUyY26p+CNxunvIMrrY=";
};
patches = [
@@ -0,0 +1,91 @@
"use strict";
const childProcess = require("child_process");
const fs = require("fs");
const [playwrightCorePath, expectedConfigPath] = process.argv.slice(2);
if (!playwrightCorePath || !expectedConfigPath) {
throw new Error("usage: browser-downloads-test.js <playwright-core> <expected-config>");
}
const browserDownloads = JSON.parse(fs.readFileSync(expectedConfigPath, "utf8"));
const browserNames = Object.keys(browserDownloads);
const hostPlatformBySystem = {
"x86_64-linux": "ubuntu22.04-x64",
"aarch64-linux": "ubuntu22.04-arm64",
"x86_64-darwin": "mac15",
"aarch64-darwin": "mac15-arm64",
};
function getRegistryDownloadURLs(hostPlatform) {
const script = `
const path = require("path");
const { registry } = require(path.join(process.env.PLAYWRIGHT_CORE_PATH, "lib/server/registry/index.js"));
const browserNames = JSON.parse(process.env.PLAYWRIGHT_BROWSER_NAMES);
const downloadURLs = Object.fromEntries(
browserNames.map((name) => [name, registry.findExecutable(name).downloadURLs]),
);
process.stdout.write(JSON.stringify(downloadURLs));
`;
return JSON.parse(
childProcess.execFileSync(process.execPath, ["-e", script], {
encoding: "utf8",
env: {
...process.env,
PLAYWRIGHT_BROWSER_NAMES: JSON.stringify(browserNames),
PLAYWRIGHT_CORE_PATH: playwrightCorePath,
PLAYWRIGHT_HOST_PLATFORM_OVERRIDE: hostPlatform,
},
}),
);
}
const failures = [];
const systems = Object.keys(browserDownloads[browserNames[0]]);
for (const system of systems) {
const hostPlatform = hostPlatformBySystem[system];
const registryDownloadURLs = getRegistryDownloadURLs(hostPlatform);
if (!hostPlatform) {
throw new Error(`unsupported system: ${system}`);
}
for (const name of browserNames) {
const expectedDownload = browserDownloads[name][system];
const actualDownloadURLs = registryDownloadURLs[name];
if (!expectedDownload) {
failures.push(`missing browser-downloads.nix entry for ${name} on ${system}`);
continue;
}
if (!Array.isArray(actualDownloadURLs) || actualDownloadURLs.length === 0) {
failures.push(`missing registry download URLs for ${name} on ${system} (${hostPlatform})`);
continue;
}
const actualDownloadURL = actualDownloadURLs[0];
if (expectedDownload.url !== actualDownloadURL) {
failures.push(
[
`${name} on ${system} (${hostPlatform}) did not match Playwright's primary download URL`,
`expected: ${browserDownloads[name][system].url}`,
`registry: ${actualDownloadURL}`,
].join("\n"),
);
}
}
}
if (failures.length > 0) {
console.error("Playwright browser download URL mismatches:");
for (const failure of failures) {
console.error(`- ${failure}`);
}
process.exit(1);
}
@@ -0,0 +1,35 @@
{
lib,
runCommand,
nodejs,
playwright-core,
}:
let
browserNames = [
"chromium"
"chromium-headless-shell"
"firefox"
"webkit"
"ffmpeg"
];
browsersJSON = (lib.importJSON ./browsers.json).browsers;
browserDownloads = lib.genAttrs browserNames (
name:
import ./browser-downloads.nix {
inherit name;
inherit (browsersJSON.${name}) revision;
browserVersion = browsersJSON.${name}.browserVersion or "";
}
);
browserDownloadsExpectedJSON = builtins.toFile "playwright-browser-downloads.json" (
builtins.toJSON browserDownloads
);
in
runCommand "playwright-browser-downloads-test"
{
nativeBuildInputs = [ nodejs ];
}
''
node ${./browser-downloads-test.js} ${playwright-core} ${browserDownloadsExpectedJSON}
touch $out
''
@@ -0,0 +1,56 @@
{
name,
revision,
browserVersion ? "",
}:
let
cftUrl =
path:
assert browserVersion != "";
"https://cdn.playwright.dev/builds/cft/${browserVersion}/${path}";
registryUrl =
browser: archive:
"https://cdn.playwright.dev/dbazure/download/playwright/builds/${browser}/${revision}/${archive}";
mk = url: stripRoot: {
inherit url stripRoot;
};
in
{
chromium = {
x86_64-linux = mk (cftUrl "linux64/chrome-linux64.zip") true;
aarch64-linux = mk (registryUrl "chromium" "chromium-linux-arm64.zip") true;
x86_64-darwin = mk (cftUrl "mac-x64/chrome-mac-x64.zip") false;
aarch64-darwin = mk (cftUrl "mac-arm64/chrome-mac-arm64.zip") false;
};
"chromium-headless-shell" = {
x86_64-linux = mk (cftUrl "linux64/chrome-headless-shell-linux64.zip") false;
aarch64-linux = mk (registryUrl "chromium" "chromium-headless-shell-linux-arm64.zip") false;
x86_64-darwin = mk (cftUrl "mac-x64/chrome-headless-shell-mac-x64.zip") false;
aarch64-darwin = mk (cftUrl "mac-arm64/chrome-headless-shell-mac-arm64.zip") false;
};
firefox = {
x86_64-linux = mk (registryUrl "firefox" "firefox-ubuntu-22.04.zip") true;
aarch64-linux = mk (registryUrl "firefox" "firefox-ubuntu-22.04-arm64.zip") true;
x86_64-darwin = mk (registryUrl "firefox" "firefox-mac.zip") false;
aarch64-darwin = mk (registryUrl "firefox" "firefox-mac-arm64.zip") false;
};
webkit = {
x86_64-linux = mk (registryUrl "webkit" "webkit-ubuntu-22.04.zip") false;
aarch64-linux = mk (registryUrl "webkit" "webkit-ubuntu-22.04-arm64.zip") false;
x86_64-darwin = mk (registryUrl "webkit" "webkit-mac-15.zip") false;
aarch64-darwin = mk (registryUrl "webkit" "webkit-mac-15-arm64.zip") false;
};
ffmpeg = {
x86_64-linux = mk (registryUrl "ffmpeg" "ffmpeg-linux.zip") false;
aarch64-linux = mk (registryUrl "ffmpeg" "ffmpeg-linux-arm64.zip") false;
x86_64-darwin = mk (registryUrl "ffmpeg" "ffmpeg-mac.zip") false;
aarch64-darwin = mk (registryUrl "ffmpeg" "ffmpeg-mac-arm64.zip") false;
};
}
.${name}
+12 -16
View File
@@ -2,34 +2,30 @@
"comment": "This file is kept up to date via update.sh",
"browsers": {
"chromium": {
"revision": "1200",
"browserVersion": "143.0.7499.4"
"revision": "1208",
"browserVersion": "145.0.7632.6",
"title": "Chrome for Testing"
},
"chromium-headless-shell": {
"revision": "1200",
"browserVersion": "143.0.7499.4"
"revision": "1208",
"browserVersion": "145.0.7632.6",
"title": "Chrome Headless Shell"
},
"firefox": {
"revision": "1497",
"browserVersion": "144.0.2"
"revision": "1509",
"browserVersion": "146.0.1",
"title": "Firefox"
},
"webkit": {
"revision": "2227",
"revision": "2248",
"revisionOverrides": {
"debian11-x64": "2105",
"debian11-arm64": "2105",
"mac10.14": "1446",
"mac10.15": "1616",
"mac11": "1816",
"mac11-arm64": "1816",
"mac12": "2009",
"mac12-arm64": "2009",
"mac13": "2140",
"mac13-arm64": "2140",
"ubuntu20.04-x64": "2092",
"ubuntu20.04-arm64": "2092"
},
"browserVersion": "26.0"
"browserVersion": "26.0",
"title": "WebKit"
},
"ffmpeg": {
"revision": "1011",
@@ -1,7 +1,7 @@
{
fetchzip,
revision,
suffix,
browserVersion,
system,
throwSystem,
stdenv,
@@ -24,15 +24,20 @@
...
}:
let
download =
(import ./browser-downloads.nix {
name = "chromium-headless-shell";
inherit revision browserVersion;
}).${system} or throwSystem;
linux = stdenv.mkDerivation {
name = "playwright-chromium-headless-shell";
src = fetchzip {
url = "https://playwright.azureedge.net/builds/chromium/${revision}/chromium-headless-shell-${suffix}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-linux = "sha256-4xPtmjRSbkWLmV2LzVClwjeQcmktZCvDS3gYo+FlkJc=";
aarch64-linux = "sha256-rnurwOiST8fdAC5kGC9uR+MRidGtIZCPQLrg+xZbuZQ=";
x86_64-linux = "sha256-/xskLzTc9tTZmu1lwkMpjV3QV7XjP92D/7zRcFuVWT8=";
aarch64-linux = "sha256-jckH5+eGJ4BhH1NAa5LIgf3/salKLAHW9XUOo5gob4c=";
}
.${system} or throwSystem;
};
@@ -64,12 +69,11 @@ let
};
darwin = fetchzip {
url = "https://playwright.azureedge.net/builds/chromium/${revision}/chromium-headless-shell-${suffix}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-darwin = "sha256-9MsBmUuaHq3P/eWxGcihzk09e1zuEr4dIMo6ZjSM8ZQ=";
aarch64-darwin = "sha256-i8L+C4p8DCcqb5C5B5q+JuX/fTPxhBva2dlFVDkdfQ0=";
x86_64-darwin = "sha256-bgU7lZhp9XUFfGu58pFdZyhXho3Jiy4MjljR+yk0M1c=";
aarch64-darwin = "sha256-45DjMIu0t7IEYdXOmIqpV/1/MKdEfx/8T7DWagh6Zhc=";
}
.${system} or throwSystem;
};
+13 -8
View File
@@ -5,7 +5,7 @@
chromium,
fetchzip,
revision,
suffix,
browserVersion,
system,
throwSystem,
lib,
@@ -41,6 +41,12 @@
...
}:
let
download =
(import ./browser-downloads.nix {
name = "chromium";
inherit revision browserVersion;
}).${system} or throwSystem;
# Playwright expects different directory names for different architectures:
# - linux-x64 expects: chrome-linux64
# - linux-arm64 expects: chrome-linux
@@ -54,11 +60,11 @@ let
chromium-linux = stdenv.mkDerivation {
name = "playwright-chromium";
src = fetchzip {
url = "https://playwright.azureedge.net/builds/chromium/${revision}/chromium-${suffix}.zip";
inherit (download) url stripRoot;
hash =
{
x86_64-linux = "sha256-r715GrQMPRIsM2/Z6SRyvo/6j4fbWXKfCCh//Cc2DGw=";
aarch64-linux = "sha256-bS8CstCia8dm2DG9vBKHjsfeoXkyBZStBefu0kD8c2o=";
x86_64-linux = "sha256-dJSO05xOzlSl/EwOWNQCeuSb+lhUU6NlGBnRu59irnM=";
aarch64-linux = "sha256-9DFLCPuc9WZjYLzlRW+Df2pb+mViPK3/IOkkUozELsw=";
}
.${system} or throwSystem;
};
@@ -121,12 +127,11 @@ let
'';
};
chromium-darwin = fetchzip {
url = "https://playwright.azureedge.net/builds/chromium/${revision}/chromium-${suffix}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-darwin = "sha256-kGHlIxS9Ti362XmBt+aepYV45cCZoBRqJ+YBsLasDp0=";
aarch64-darwin = "sha256-LwY25Ckh1ZY+L196shf8ydF4IHXUIeI83Yqp8KG+nc4=";
x86_64-darwin = "sha256-vQuBHM0jkk6S/Gco/bBqSPJqXi/CJt/+nkbGtFNpgwk=";
aarch64-darwin = "sha256-qXdgHeBS5IFIa4hZVmjq0+31v/uDPXHyc4aH7Wn2E7E=";
}
.${system} or throwSystem;
};
+22 -28
View File
@@ -11,36 +11,28 @@
callPackage,
makeFontsConf,
makeWrapper,
runCommand,
cacert,
}:
let
inherit (stdenv.hostPlatform) system;
throwSystem = throw "Unsupported system: ${system}";
suffix =
{
x86_64-linux = "linux";
aarch64-linux = "linux-arm64";
x86_64-darwin = "mac";
aarch64-darwin = "mac-arm64";
}
.${system} or throwSystem;
browsersJSON = (lib.importJSON ./browsers.json).browsers;
version = "1.57.0";
version = "1.58.2";
src = fetchFromGitHub {
owner = "Microsoft";
repo = "playwright";
rev = "v${version}";
hash = "sha256-1g8XCToVKWOjLpWS6g60FpoIphg9Rn/nv10oRa7oyDA=";
hash = "sha256-PRA3hjMlnHGVMidhEo371WXRPyVP2W0rle8ONUlKg9Y=";
};
babel-bundle = buildNpmPackage {
pname = "babel-bundle";
inherit version src;
sourceRoot = "${src.name}/packages/playwright/bundles/babel";
npmDepsHash = "sha256-ByCy4go8PM0ksDg+2DcJPyoKG7Z0uIqKM647ZQwYwAE=";
npmDepsHash = "sha256-MVMxYncmIA4k6h7mLirJaroOSNbCpvKSGxN3BGGqJ9w=";
dontNpmBuild = true;
installPhase = ''
cp -r . "$out"
@@ -60,7 +52,7 @@ let
pname = "utils-bundle";
inherit version src;
sourceRoot = "${src.name}/packages/playwright/bundles/utils";
npmDepsHash = "sha256-InwWYRk6eRF62qI6qpVaPceIetSr3kPIBK4LdfeoJdo=";
npmDepsHash = "sha256-HzMu3xDb7MleJSsQ1+VvpIFSxcRfnVXniYIv/c5PHRg=";
dontNpmBuild = true;
installPhase = ''
cp -r . "$out"
@@ -70,7 +62,7 @@ let
pname = "utils-bundle-core";
inherit version src;
sourceRoot = "${src.name}/packages/playwright-core/bundles/utils";
npmDepsHash = "sha256-lOwcHRpv7OKfdnwqHxvh+Gy5AE/Up3Vro4czedNiOpc=";
npmDepsHash = "sha256-/nxMK+gr4jmxeUazLRXd9LXdYYBVY9VnzbbXoxazX7c=";
dontNpmBuild = true;
installPhase = ''
cp -r . "$out"
@@ -92,7 +84,7 @@ let
inherit version src;
sourceRoot = "${src.name}"; # update.sh depends on sourceRoot presence
npmDepsHash = "sha256-69v+H3EQuJadma8b/l9rA/yMFCCb7wWiBGN/LoJLJM8=";
npmDepsHash = "sha256-kc77z9REuV7b+zHcUzBLf7F2+cbAhzD/kaGxa6xNnGo=";
nativeBuildInputs = [
cacert
@@ -164,7 +156,7 @@ let
'';
passthru = {
browsersJSON = (lib.importJSON ./browsers.json).browsers;
inherit browsersJSON;
selectBrowsers = browsers;
browsers = browsers { };
browsers-chromium = browsers {
@@ -172,6 +164,9 @@ let
withWebkit = false;
withChromiumHeadlessShell = false;
};
tests.browser-downloads = callPackage ./browser-downloads-test.nix {
playwright-core = finalAttrs.finalPackage;
};
inherit components;
updateScript = ./update.sh;
};
@@ -204,27 +199,27 @@ let
components = {
chromium = callPackage ./chromium.nix {
inherit suffix system throwSystem;
inherit (playwright-core.passthru.browsersJSON.chromium) revision;
inherit system throwSystem;
inherit (browsersJSON.chromium) revision browserVersion;
fontconfig_file = makeFontsConf {
fontDirectories = [ ];
};
};
chromium-headless-shell = callPackage ./chromium-headless-shell.nix {
inherit suffix system throwSystem;
inherit (playwright-core.passthru.browsersJSON.chromium) revision;
inherit system throwSystem;
inherit (browsersJSON."chromium-headless-shell") revision browserVersion;
};
firefox = callPackage ./firefox.nix {
inherit suffix system throwSystem;
inherit (playwright-core.passthru.browsersJSON.firefox) revision;
inherit system throwSystem;
inherit (browsersJSON.firefox) revision;
};
webkit = callPackage ./webkit.nix {
inherit suffix system throwSystem;
inherit (playwright-core.passthru.browsersJSON.webkit) revision;
inherit system throwSystem;
inherit (browsersJSON.webkit) revision;
};
ffmpeg = callPackage ./ffmpeg.nix {
inherit suffix system throwSystem;
inherit (playwright-core.passthru.browsersJSON.ffmpeg) revision;
inherit system throwSystem;
inherit (browsersJSON.ffmpeg) revision;
};
};
@@ -252,8 +247,7 @@ let
map (
name:
let
revName = if name == "chromium-headless-shell" then "chromium" else name;
value = playwright-core.passthru.browsersJSON.${revName};
value = browsersJSON.${name};
in
lib.nameValuePair
# TODO check platform for revisionOverrides
+8 -3
View File
@@ -1,13 +1,18 @@
{
fetchzip,
suffix,
revision,
system,
throwSystem,
}:
let
download =
(import ./browser-downloads.nix {
name = "ffmpeg";
inherit revision;
}).${system} or throwSystem;
in
fetchzip {
url = "https://playwright.azureedge.net/builds/ffmpeg/${revision}/ffmpeg-${suffix}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-linux = "sha256-AWTiui+ccKHxsIaQSgc5gWCJT5gYwIWzAEqSuKgVqZU=";
+12 -11
View File
@@ -1,24 +1,26 @@
{
lib,
stdenv,
fetchzip,
firefox-bin,
suffix,
revision,
system,
throwSystem,
}:
let
download =
(import ./browser-downloads.nix {
name = "firefox";
inherit revision;
}).${system} or throwSystem;
firefox-linux = stdenv.mkDerivation {
name = "playwright-firefox";
src = fetchzip {
url = "https://playwright.azureedge.net/builds/firefox/${revision}/firefox-${
"ubuntu-22.04" + (lib.removePrefix "linux" suffix)
}.zip";
inherit (download) url stripRoot;
hash =
{
x86_64-linux = "sha256-PGTFoSjU2FFRmH7qfWkJsgnGvg3AI+eGrNUwyxRU8PM=";
aarch64-linux = "sha256-P5aHwaNZ0KfAVgRVugvAl6FsQu2/7sphwulOVyXiTgg=";
x86_64-linux = "sha256-HBmCV6AFdQ2qTuCIa7WaCiSHU8Am7S+xhpmEWU6DL/U=";
aarch64-linux = "sha256-peP032z4GOoUp1WAszvzyeXnROw6RwRffG+KRe1Qf9k=";
}
.${system} or throwSystem;
};
@@ -37,12 +39,11 @@ let
'';
};
firefox-darwin = fetchzip {
url = "https://playwright.azureedge.net/builds/firefox/${revision}/firefox-${suffix}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-darwin = "sha256-MI4HfXLmVEwcoL2jlcrDkfiClEN5rI8YcJiMqzE1xYs=";
aarch64-darwin = "sha256-Il7bTQoP6ZlqizduV4iCTrVsymy33RbGQtVSnVXnhTc=";
x86_64-darwin = "sha256-uxPOq2U1D9gFXqvNzclctLbHx4fZ9O92GtDQjCRYGiM=";
aarch64-darwin = "sha256-ZFRmtlNrzrjB3ELXmGC67XO1IhfWsWZ7rXaUQ6If65s=";
}
.${system} or throwSystem;
};
+132 -88
View File
@@ -1,90 +1,146 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p curl gnused common-updater-scripts jq prefetch-npm-deps unzip nix-prefetch
# shellcheck shell=bash
set -euo pipefail
root="$(dirname "$(readlink -f "$0")")"
repo_root="$(git -C "$root" rev-parse --show-toplevel)"
cd "$repo_root"
version=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} -s https://api.github.com/repos/microsoft/playwright-python/releases/latest | jq -r '.tag_name | sub("^v"; "")')
github_api_curl_args=()
if [ -n "${GITHUB_TOKEN:-}" ]; then
github_api_curl_args=(-u ":$GITHUB_TOKEN")
fi
playwright_browsers_file="$root/browsers.json"
playwright_driver_file="$root/driver.nix"
playwright_raw_repo_url="https://raw.githubusercontent.com/microsoft/playwright"
playwright_mcp_package_file="$root/../../../by-name/pl/playwright-mcp/package.nix"
browser_names=(chromium chromium-headless-shell firefox webkit ffmpeg)
browser_systems=(x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin)
github_api_get() {
curl "${github_api_curl_args[@]}" -fsSL "$1"
}
major_minor() {
echo "${1%.*}"
}
python_version=$(github_api_get https://api.github.com/repos/microsoft/playwright-python/releases/latest | jq -r '.tag_name | sub("^v"; "")')
# Most of the time, this should be the latest stable release of the Node-based
# Playwright version, but that isn't a guarantee, so this needs to be specified
# as well:
setup_py_url="https://github.com/microsoft/playwright-python/raw/v${version}/setup.py"
driver_version=$(curl -Ls "$setup_py_url" | grep '^driver_version =' | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')
# Playwright version, but upstream occasionally ships additional npm-only patch
# releases. Resolve the latest patch in the same major.minor series.
setup_py_url="https://github.com/microsoft/playwright-python/raw/v${python_version}/setup.py"
python_driver_version=$(curl -fsSL "$setup_py_url" | grep '^driver_version =' | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+')
python_major_minor=$(major_minor "$python_driver_version")
resolve_driver_version_latest_patch() {
local mm_escaped
mm_escaped=${python_major_minor//./\\.}
curl -fsSL "https://registry.npmjs.org/playwright" \
| jq -r '.versions | keys[]' \
| grep -E "^${mm_escaped}\.[0-9]+$" \
| sort -V \
| tail -n1
}
driver_version="$(resolve_driver_version_latest_patch)"
: "${driver_version:?failed to resolve driver version from npm for python major.minor ${python_major_minor}}"
: "${python_driver_version:?failed to resolve driver_version from ${setup_py_url}}"
# TODO: skip if update-source-version reported the same version
update-source-version playwright-driver "$driver_version"
update-source-version python3Packages.playwright "$version"
driver_file="$root/driver.nix"
repo_url_prefix="https://github.com/microsoft/playwright/raw"
update-source-version python3Packages.playwright "$python_version"
temp_dir=$(mktemp -d)
trap 'rm -rf "$temp_dir"' EXIT
# Update playwright-mcp package
mcp_version=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} -s https://api.github.com/repos/microsoft/playwright-mcp/releases/latest | jq -r '.tag_name | sub("^v"; "")')
driver_major_minor=$(major_minor "$driver_version")
resolve_mcp_version() {
local releases_json
local tag_name
releases_json=$(github_api_get "https://api.github.com/repos/microsoft/playwright-mcp/releases?per_page=100")
while IFS= read -r tag_name; do
local mcp_version_candidate mcp_npm_url mcp_playwright_dep mcp_major_minor
mcp_version_candidate=${tag_name#v}
mcp_npm_url="https://registry.npmjs.org/@playwright/mcp/${mcp_version_candidate}"
mcp_playwright_dep=$(
curl -fsSL "$mcp_npm_url" \
| jq -r '.dependencies.playwright // .dependencies["playwright-core"] // empty'
) || continue
mcp_major_minor=$(echo "$mcp_playwright_dep" | grep -Eo '[0-9]+\.[0-9]+' | head -n1 || true)
if [ "$mcp_major_minor" = "$driver_major_minor" ]; then
echo "$mcp_version_candidate"
return 0
fi
done < <(echo "$releases_json" | jq -r '.[].tag_name')
return 1
}
mcp_version="$(resolve_mcp_version)" || {
echo "Could not find a playwright-mcp release compatible with Playwright driver ${driver_version}" >&2
exit 1
}
update-source-version playwright-mcp "$mcp_version"
# Update npmDepsHash for playwright-mcp
pushd "$temp_dir" >/dev/null
curl -fsSL -o package-lock.json "https://raw.githubusercontent.com/microsoft/playwright-mcp/v${mcp_version}/package-lock.json"
mcp_npm_hash=$(prefetch-npm-deps package-lock.json)
rm -f package-lock.json
popd >/dev/null
mcp_lock_file="${temp_dir}/playwright-mcp-package-lock.json"
curl -fsSL -o "$mcp_lock_file" "https://raw.githubusercontent.com/microsoft/playwright-mcp/v${mcp_version}/package-lock.json"
mcp_npm_hash=$(prefetch-npm-deps "$mcp_lock_file")
mcp_package_file="$root/../../../by-name/pl/playwright-mcp/package.nix"
sed -E 's#\bnpmDepsHash = ".*?"#npmDepsHash = "'"$mcp_npm_hash"'"#' -i "$mcp_package_file"
sed -E -i 's#\bnpmDepsHash = "[^"]*"#npmDepsHash = "'"$mcp_npm_hash"'"#' "$playwright_mcp_package_file"
# update binaries of browsers, used by playwright.
replace_sha() {
sed -i "s|$2 = \".\{44,52\}\"|$2 = \"$3\"|" "$1"
local target_file="$1"
local attr_name="$2"
local new_hash="$3"
sed -i "s|$attr_name = \".\{44,52\}\"|$attr_name = \"$new_hash\"|" "$target_file"
}
prefetch_browser() {
# nix-prefetch is used to obtain sha with `stripRoot = false`
# doesn't work on macOS https://github.com/msteen/nix-prefetch/issues/53
nix-prefetch --option extra-experimental-features flakes -q "{ stdenv, fetchzip }: stdenv.mkDerivation { name=\"browser\"; src = fetchzip { url = \"$1\"; stripRoot = $2; }; }"
local url="$1"
local strip_root="$2"
# nix-prefetch is used to obtain sha with `stripRoot = false`
# doesn't work on macOS https://github.com/msteen/nix-prefetch/issues/53
nix-prefetch --option extra-experimental-features flakes -q "{ stdenv, fetchzip }: stdenv.mkDerivation { name=\"browser\"; src = fetchzip { url = \"$url\"; stripRoot = $strip_root; }; }"
}
browser_download_info() {
local name="$1"
local revision="$2"
local browser_version="$3"
nix-instantiate --eval --json --strict "$root/browser-downloads.nix" \
--argstr name "$name" \
--argstr revision "$revision" \
--argstr browserVersion "$browser_version"
}
update_browser() {
name="$1"
platform="$2"
stripRoot="false"
if [ "$platform" = "darwin" ]; then
if [ "$name" = "webkit" ]; then
suffix="mac-14"
else
suffix="mac"
fi
else
if [ "$name" = "ffmpeg" ] || [ "$name" = "chromium-headless-shell" ]; then
suffix="linux"
elif [ "$name" = "chromium" ]; then
stripRoot="true"
suffix="linux"
elif [ "$name" = "firefox" ]; then
stripRoot="true"
suffix="ubuntu-22.04"
else
suffix="ubuntu-22.04"
fi
fi
aarch64_suffix="$suffix-arm64"
if [ "$name" = "chromium-headless-shell" ]; then
buildname="chromium";
else
buildname="$name"
fi
local name="$1"
local revision
local browser_version
local download_info
local system
local url
local strip_root
revision="$(jq -r ".browsers[\"$buildname\"].revision" "$root/browsers.json")"
replace_sha "$root/$name.nix" "x86_64-$platform" \
"$(prefetch_browser "https://playwright.azureedge.net/builds/$buildname/$revision/$name-$suffix.zip" $stripRoot)"
replace_sha "$root/$name.nix" "aarch64-$platform" \
"$(prefetch_browser "https://playwright.azureedge.net/builds/$buildname/$revision/$name-$aarch64_suffix.zip" $stripRoot)"
revision="$(jq -r ".browsers[\"$name\"].revision" "$playwright_browsers_file")"
browser_version="$(jq -r ".browsers[\"$name\"].browserVersion // empty" "$playwright_browsers_file")"
download_info="$(browser_download_info "$name" "$revision" "$browser_version")"
for system in "${browser_systems[@]}"; do
url="$(echo "$download_info" | jq -r --arg system "$system" '.[$system].url')"
strip_root="$(echo "$download_info" | jq -r --arg system "$system" '.[$system].stripRoot')"
replace_sha "$root/$name.nix" "$system" "$(prefetch_browser "$url" "$strip_root")"
done
}
curl -fsSl \
curl -fsSL \
"https://raw.githubusercontent.com/microsoft/playwright/v${driver_version}/packages/playwright-core/browsers.json" \
| jq '
.comment = "This file is kept up to date via update.sh"
@@ -94,46 +150,34 @@ curl -fsSl \
| map({(.name): . | del(.name)})
| add
)
' > "$root/browsers.json"
' > "$playwright_browsers_file"
update_browser "chromium" "linux"
update_browser "chromium-headless-shell" "linux"
update_browser "firefox" "linux"
update_browser "webkit" "linux"
update_browser "ffmpeg" "linux"
update_browser "chromium" "darwin"
update_browser "chromium-headless-shell" "darwin"
update_browser "firefox" "darwin"
update_browser "webkit" "darwin"
update_browser "ffmpeg" "darwin"
for browser in "${browser_names[@]}"; do
update_browser "$browser"
done
# Update package-lock.json files for all npm deps that are built in playwright
# Function to download `package-lock.json` for a given source path and update hash
# Download `package-lock.json` for a given sourceRoot path and update its hash.
update_hash() {
local source_root_path="$1"
local existing_hash="$2"
# Formulate download URL
local download_url="${repo_url_prefix}/v${driver_version}${source_root_path}/package-lock.json"
# Download package-lock.json to temporary directory
curl -fsSL -o "${temp_dir}/package-lock.json" "$download_url"
# Calculate the new hash
local download_url
local lock_file
local new_hash
new_hash=$(prefetch-npm-deps "${temp_dir}/package-lock.json")
local source_root_pattern
# Update npmDepsHash in the original file
sed -i "s|$existing_hash|${new_hash}|" "$driver_file"
download_url="${playwright_raw_repo_url}/v${driver_version}${source_root_path}/package-lock.json"
lock_file="${temp_dir}/$(echo "$source_root_path" | tr '/.' '__').package-lock.json"
curl -fsSL -o "$lock_file" "$download_url"
new_hash=$(prefetch-npm-deps "$lock_file")
source_root_pattern=$(printf '%s\n' "$source_root_path" | sed 's/[][\\/.*^$+?(){}|]/\\&/g')
sed -E -i "/sourceRoot = \"\\\$\\{src.name\\}${source_root_pattern}\";/,/npmDepsHash = / s#npmDepsHash = \"[^\"]*\";#npmDepsHash = \"${new_hash}\";#" "$playwright_driver_file"
}
while IFS= read -r source_root_line; do
[[ "$source_root_line" =~ sourceRoot ]] || continue
source_root_path=$(echo "$source_root_line" | sed -e 's/^.*"${src.name}\(.*\)";.*$/\1/')
# Extract the current npmDepsHash for this sourceRoot
existing_hash=$(grep -A1 "$source_root_line" "$driver_file" | grep 'npmDepsHash' | sed -e 's/^.*npmDepsHash = "\(.*\)";$/\1/')
# Call the function to download and update the hash
update_hash "$source_root_path" "$existing_hash"
done < "$driver_file"
while IFS= read -r source_root_path; do
update_hash "$source_root_path"
done < <(
# shellcheck disable=SC2016
sed -n 's#^[[:space:]]*sourceRoot = "${src.name}\(.*\)";.*$#\1#p' "$playwright_driver_file"
)
+11 -16
View File
@@ -46,19 +46,16 @@
wayland-scanner,
woff2,
zlib,
suffix,
revision,
system,
throwSystem,
}:
let
suffix' =
if lib.hasPrefix "linux" suffix then
"ubuntu-22.04" + (lib.removePrefix "linux" suffix)
else if lib.hasPrefix "mac" suffix then
"mac-14" + (lib.removePrefix "mac" suffix)
else
suffix;
download =
(import ./browser-downloads.nix {
name = "webkit";
inherit revision;
}).${system} or throwSystem;
libvpx' = libvpx.overrideAttrs (
finalAttrs: previousAttrs: {
version = "1.12.0";
@@ -133,12 +130,11 @@ let
webkit-linux = stdenv.mkDerivation {
name = "playwright-webkit";
src = fetchzip {
url = "https://playwright.azureedge.net/builds/webkit/${revision}/webkit-${suffix'}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-linux = "sha256-wSMObGeDoy1vW7TO20wL3vWOSpcDgFciK00SqZ15EjM=";
aarch64-linux = "sha256-IyZNAcAUxDpCgc/I2dWtIoRqKiZJ1ggmYqqdvUKg6IE=";
x86_64-linux = "sha256-h9dM6RR5WhUPHdZgn5yiJlM7QrhlDVaivnaHQCEZbXQ=";
aarch64-linux = "sha256-sOtPdOBmPLqApGGVhgH51OW3aoTv1Y40RfCSax7CyC4=";
}
.${system} or throwSystem;
};
@@ -214,12 +210,11 @@ let
'';
};
webkit-darwin = fetchzip {
url = "https://playwright.azureedge.net/builds/webkit/${revision}/webkit-${suffix'}.zip";
stripRoot = false;
inherit (download) url stripRoot;
hash =
{
x86_64-darwin = "sha256-a8NKlNhKPEhtWREAgNosvTLE+zphmKYW+CtvW5jwFlQ=";
aarch64-darwin = "sha256-DvVTVAxuh4we2278xZFBomFAxcuqyEOCK7mPg3rnYpU=";
x86_64-darwin = "sha256-An3sdw8HltgHQ6YASsxyhoK1fd8PxZ0BBCMpnOORkv8=";
aarch64-darwin = "sha256-suXPCuXLMz3xoFxE5+Yjd9OXxLfNDDJiU6O1Ic0PsOI=";
}
.${system} or throwSystem;
};