1{ lib 2, stdenv 3, buildPythonPackage 4, chromium 5, ffmpeg 6, firefox 7, git 8, greenlet 9, jq 10, nodejs 11, fetchFromGitHub 12, fetchurl 13, makeFontsConf 14, makeWrapper 15, pyee 16, python 17, pythonOlder 18, runCommand 19, setuptools-scm 20, unzip 21}: 22 23let 24 inherit (stdenv.hostPlatform) system; 25 throwSystem = throw "Unsupported system: ${system}"; 26 27 driverVersion = "1.27.1"; 28 29 driver = let 30 suffix = { 31 x86_64-linux = "linux"; 32 aarch64-linux = "linux-arm64"; 33 x86_64-darwin = "mac"; 34 aarch64-darwin = "mac-arm64"; 35 }.${system} or throwSystem; 36 filename = "playwright-${driverVersion}-${suffix}.zip"; 37 in stdenv.mkDerivation { 38 pname = "playwright-driver"; 39 version = driverVersion; 40 41 src = fetchurl { 42 url = "https://playwright.azureedge.net/builds/driver/${filename}"; 43 sha256 = { 44 x86_64-linux = "0x71b4kb8hlyacixipgfbgjgrbmhckxpbmrs2xk8iis7n5kg7539"; 45 aarch64-linux = "125lih7g2gj91k7j196wy5a5746wyfr8idj3ng369yh5wl7lfcfv"; 46 x86_64-darwin = "0z2kww4iby1izkwn6z2ai94y87bkjvwak8awdmjm8sgg00pa9l1a"; 47 aarch64-darwin = "0qajh4ac5lr1sznb2c471r5c5g2r0dk2pyqz8vhvnbk36r524h1h"; 48 }.${system} or throwSystem; 49 }; 50 51 sourceRoot = "."; 52 53 nativeBuildInputs = [ unzip ]; 54 55 postPatch = '' 56 # Use Nix's NodeJS instead of the bundled one. 57 substituteInPlace playwright.sh --replace '"$SCRIPT_PATH/node"' '"${nodejs}/bin/node"' 58 rm node 59 60 # Hard-code the script path to $out directory to avoid a dependency on coreutils 61 substituteInPlace playwright.sh \ 62 --replace 'SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"' "SCRIPT_PATH=$out" 63 64 patchShebangs playwright.sh package/bin/*.sh 65 ''; 66 67 installPhase = '' 68 runHook preInstall 69 70 mkdir -p $out/bin 71 mv playwright.sh $out/bin/playwright 72 mv package $out/ 73 74 runHook postInstall 75 ''; 76 77 passthru = { 78 inherit filename; 79 }; 80 }; 81 82 browsers-mac = stdenv.mkDerivation { 83 pname = "playwright-browsers"; 84 version = driverVersion; 85 86 src = runCommand "playwright-browsers-base" { 87 outputHashMode = "recursive"; 88 outputHashAlgo = "sha256"; 89 outputHash = { 90 x86_64-darwin = "0z2kww4iby1izkwn6z2ai94y87bkjvwak8awdmjm8sgg00pa9l1a"; 91 }.${system} or throwSystem; 92 } '' 93 export PLAYWRIGHT_BROWSERS_PATH=$out 94 ${driver}/bin/playwright install 95 rm -r $out/.links 96 ''; 97 98 installPhase = '' 99 mkdir $out 100 cp -r * $out/ 101 ''; 102 }; 103 104 browsers-linux = { withFirefox ? true, withChromium ? true }: let 105 fontconfig = makeFontsConf { 106 fontDirectories = []; 107 }; 108 in runCommand ("playwright-browsers" 109 + lib.optionalString (withFirefox && !withChromium) "-firefox" 110 + lib.optionalString (!withFirefox && withChromium) "-chromium") 111 { 112 nativeBuildInputs = [ 113 makeWrapper 114 jq 115 ]; 116 } ('' 117 BROWSERS_JSON=${driver}/package/browsers.json 118 '' + lib.optionalString withChromium '' 119 CHROMIUM_REVISION=$(jq -r '.browsers[] | select(.name == "chromium").revision' $BROWSERS_JSON) 120 mkdir -p $out/chromium-$CHROMIUM_REVISION/chrome-linux 121 122 # See here for the Chrome options: 123 # https://github.com/NixOS/nixpkgs/issues/136207#issuecomment-908637738 124 makeWrapper ${chromium}/bin/chromium $out/chromium-$CHROMIUM_REVISION/chrome-linux/chrome \ 125 --set SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt \ 126 --set FONTCONFIG_FILE ${fontconfig} 127 '' + lib.optionalString withFirefox '' 128 FIREFOX_REVISION=$(jq -r '.browsers[] | select(.name == "firefox").revision' $BROWSERS_JSON) 129 mkdir -p $out/firefox-$FIREFOX_REVISION/firefox 130 ln -s ${firefox}/bin/firefox $out/firefox-$FIREFOX_REVISION/firefox/firefox 131 '' + '' 132 FFMPEG_REVISION=$(jq -r '.browsers[] | select(.name == "ffmpeg").revision' $BROWSERS_JSON) 133 mkdir -p $out/ffmpeg-$FFMPEG_REVISION 134 ln -s ${ffmpeg}/bin/ffmpeg $out/ffmpeg-$FFMPEG_REVISION/ffmpeg-linux 135 ''); 136in 137buildPythonPackage rec { 138 pname = "playwright"; 139 version = "1.27.1"; 140 format = "setuptools"; 141 disabled = pythonOlder "3.7"; 142 143 src = fetchFromGitHub { 144 owner = "microsoft"; 145 repo = "playwright-python"; 146 rev = "v${version}"; 147 sha256 = "sha256-cI/4GdkmTikoP9O0Skh/0jCxxRypRua0231iKcxtBcY="; 148 }; 149 150 patches = [ 151 # This patches two things: 152 # - The driver location, which is now a static package in the Nix store. 153 # - The setup script, which would try to download the driver package from 154 # a CDN and patch wheels so that they include it. We don't want this 155 # we have our own driver build. 156 ./driver-location.patch 157 ]; 158 159 postPatch = '' 160 # if setuptools_scm is not listing files via git almost all python files are excluded 161 export HOME=$(mktemp -d) 162 git init . 163 git add -A . 164 git config --global user.email "nixpkgs" 165 git config --global user.name "nixpkgs" 166 git commit -m "workaround setuptools-scm" 167 168 substituteInPlace setup.py \ 169 --replace "greenlet==1.1.3" "greenlet>=1.1.3" \ 170 --replace "pyee==8.1.0" "pyee>=8.1.0" \ 171 --replace "setuptools-scm==7.0.5" "setuptools-scm>=7.0.5" \ 172 --replace "wheel==0.37.1" "wheel>=0.37.1" 173 174 # Skip trying to download and extract the driver. 175 # This is done manually in postInstall instead. 176 substituteInPlace setup.py \ 177 --replace "self._download_and_extract_local_driver(base_wheel_bundles)" "" 178 179 # Set the correct driver path with the help of a patch in patches 180 substituteInPlace playwright/_impl/_driver.py \ 181 --replace "@driver@" "${driver}/bin/playwright" 182 ''; 183 184 185 nativeBuildInputs = [ git setuptools-scm ]; 186 187 propagatedBuildInputs = [ 188 greenlet 189 pyee 190 ]; 191 192 postInstall = '' 193 ln -s ${driver} $out/${python.sitePackages}/playwright/driver 194 ''; 195 196 # Skip tests because they require network access. 197 doCheck = false; 198 199 pythonImportsCheck = [ 200 "playwright" 201 ]; 202 203 passthru = rec { 204 inherit driver; 205 browsers = { 206 x86_64-linux = browsers-linux { }; 207 aarch64-linux = browsers-linux { }; 208 x86_64-darwin = browsers-mac; 209 aarch64-darwin = browsers-mac; 210 }.${system} or throwSystem; 211 browsers-chromium = browsers-linux { withFirefox = false; }; 212 browsers-firefox = browsers-linux { withChromium = false; }; 213 214 tests = { 215 inherit driver browsers; 216 }; 217 }; 218 219 meta = with lib; { 220 description = "Python version of the Playwright testing and automation library"; 221 homepage = "https://github.com/microsoft/playwright-python"; 222 license = licenses.asl20; 223 maintainers = with maintainers; [ techknowlogick yrd SuperSandro2000 ]; 224 }; 225}