Cypress UI testing issue

Anyone using https://www.cypress.io/ to test UI of web applications?
I am having trouble running it on my newly install nixos.
It’s an npm package that installs a binary. The installation goes smoothly but calling
$(npm bin)/cypress open
fails with a message about dependencies.
The deps are expressed here:
Introduction | Cypress Documentation
apt-get install xvfb libgtk2.0-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2
I cannot match many of these to the published packages in NixOS Search

I was able to run it like this:

cypress.nix:

with import <nixpkgs> {};

let

  version = "3.1.5";

  rpath = stdenv.lib.makeLibraryPath [
    alsaLib
    atk
    cairo
    cups
    dbus
    expat
    fontconfig
    freetype
    glib
    gnome2.GConf
    gdk_pixbuf
    gtk2
    pango
    libnotify
    nspr
    nss
    stdenv.cc.cc
    systemd

    xorg.libxcb
    xorg.libxkbfile
    xorg.libX11
    xorg.libXcomposite
    xorg.libXcursor
    xorg.libXdamage
    xorg.libXext
    xorg.libXfixes
    xorg.libXi
    xorg.libXrandr
    xorg.libXrender
    xorg.libXtst
    xorg.libXScrnSaver
  ] + ":${stdenv.cc.cc.lib}/lib64";

  src =
    if stdenv.hostPlatform.system == "x86_64-linux" then
      fetchurl {
        url = "https://cdn.cypress.io/desktop/${version}/linux64/cypress.zip";
        sha256 = "19ilnb0ww8zvzxv0pq0qsjy6zp789c26rw6559j8q2s3f59jqv05";
      }
    else
      throw "Cypress is not supported on ${stdenv.hostPlatform.system}";

in stdenv.mkDerivation {
  name = "cypress-${version}";

  inherit src;

  nativeBuildInputs = [ unzip ];

  buildCommand = ''
    mkdir -p $out
    unzip -d $out $src

    for file in $out/Cypress/Cypress $(find $out -type f -name \*.so\*); do
    echo $file
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$file" || true
      patchelf --set-rpath ${rpath}:$out/Cypress $file || true
    done

    # At the first run, the npm package would try to create the
    # binary_state.json file in the directory of the Cypress executable. That
    # would fail, because the Nix store is not writable. Let's create the file
    # ourselves to make the npm package happy.
    echo '{"verified": true}' >$out/Cypress/binary_state.json
  '';

  meta = with stdenv.lib; {
    description = "Web front end testing tool based on Electron";
    homepage = https://cypress.io/;
    license = licenses.unfree;
    platforms = [ "x86_64-linux" ];
  };
}

$ nix-build cypress.nix

It is now possible to run the Cypress binary directly:

$ ./result/Cypress/Cypress

Now we can tell the npm module to use the patched Cypress binary:

$ export CYPRESS_INSTALL_BINARY=0
$ export CYPRESS_RUN_BINARY=./result/Cypress/Cypress

After that, everything should work.

Would be nice to build Cypress (and Electron) from sources, but that’s probably another story.

2 Likes

Wow… this is pretty amazing.
I did kind of a hack, reusing atomEnv. Here is my pull request, but I think the “merge gods” would be happier from your solution than mine since it’s clean, complete and only includes the specific required libs.
I’ll be happy to see your pull request merged.
My patch/binary works locally, I tested it with a current project I am working on. Let me know if you have any clue how this can be implemented into the npm install cypress to submit to Cypress in NixOS not working · Issue #3530 · cypress-io/cypress · GitHub
Thanks so much for your help.

You are free to use the code to improve your merge request, if you want. :slight_smile:

I think you should use autoPatchelfHook.
This is the derivation I use:

{stdenv, fetchurl, autoPatchelfHook, xorg, gtk2, gnome2, nss, alsaLib, udev, unzip}:
stdenv.mkDerivation rec{
  version = "3.1.5";
  name = "cypress-${version}";
  src = fetchurl {
    url = "https://download.cypress.io/desktop/${version}?platform=linux64";
    sha256 = "19ilnb0ww8zvzxv0pq0qsjy6zp789c26rw6559j8q2s3f59jqv05";
  };

  # don't remove runtime deps
  dontPatchELF = true;

  nativeBuildInputs = [ autoPatchelfHook ];

  buildInputs = with xorg; [
    libXScrnSaver libXdamage libXtst 
  ] ++ [
    nss gtk2 alsaLib gnome2.GConf unzip
  ];

  runtimeDependencies = [ udev.lib ];

  unpackCmd = ''
    unzip $curSrc
  '';

  installPhase = ''
    ls -la
    mkdir -p $out/bin $out/opt/cypress
    cp -r * $out/opt/cypress
    ln -s $out/opt/cypress/Cypress $out/bin/Cypress
  '';

  meta = with stdenv.lib; {
    description = "Fast, easy and reliable testing for anything that runs in a browser.";
    homepage = https://www.cypress.io;
    license = licenses.mit;
    platforms = ["x86_64-linux"];
  };
}
1 Like