Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save r-k-b/2485f977b476aa3f76a47329ce7f9ad4 to your computer and use it in GitHub Desktop.
Save r-k-b/2485f977b476aa3f76a47329ce7f9ad4 to your computer and use it in GitHub Desktop.
how to use NixOS's Cypress instead of npm's Cypress

Should help with avoiding errors like:

No version of Cypress is installed in: /home/rkb/.cache/Cypress/6.2.1/Cypress

Please reinstall Cypress by running: cypress install

----------

Cypress executable not found at: /home/rkb/.cache/Cypress/6.2.1/Cypress/Cypress

----------

Platform: linux (NixOS - )
Cypress Version: 6.2.1

and

Cypress failed to start.

This is usually caused by a missing library or dependency.

The error below should indicate which dependency is missing.

https://on.cypress.io/required-dependencies

If you are using Docker, we provide containers with all required dependencies installed.

----------

Command failed with ENOENT: /home/rkb/.cache/Cypress/6.2.1/Cypress/Cypress --no-sandbox --smoke-test --ping=459
spawn /home/rkb/.cache/Cypress/6.2.1/Cypress/Cypress ENOENT

----------

Platform: linux (NixOS - )
Cypress Version: 6.2.1

todo

EACCES: permission denied, open '/home/rkb/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/background.js'

apply this patch to Cypress from within the shell.nix (or get it upstreamed?) done. Super hacky, but done!

# When Cypress starts, it copies some files into `~/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/`
# from the Nix Store, one of which it attempts to modify immediately after.
# As-is, this fails because the copied file keeps the read-only flag it had in
# the Store.
# Luckily, the code responsible is a plain text script that we can easily patch:
final: prev: {
cypress = prev.cypress.overrideAttrs (oldAttrs: {
installPhase = let
old = "copyExtension(pathToExtension, extensionDest)";
# This has only been tested against Cypress 6.0.0!
newForChrome =
"copyExtension(pathToExtension, extensionDest).then(() => fs_1.default.chmodAsync(extensionBg, 0o0644))";
newForFirefox =
"copyExtension(pathToExtension, extensionDest).then(() => fs.chmodAsync(extensionBg, 0o0644))";
in ''
sed -i 's/${old}/${newForChrome}/' \
./resources/app/packages/server/lib/browsers/chrome.js
sed -i 's/${old}/${newForFirefox}/' \
./resources/app/packages/server/lib/browsers/utils.js
'' + oldAttrs.installPhase;
});
}
let pkgs = import <nixpkgs> { overlays = [ (import ./cypress-overlay.nix) ]; };
in pkgs.mkShell {
name = "cypress-example";
buildInputs = with pkgs; [
cypress
(with dotnetCorePackages; combinePackages [ sdk_5_0 net_5_0 ])
nodejs
];
shellHook = ''
export CYPRESS_INSTALL_BINARY=0
export CYPRESS_RUN_BINARY=${pkgs.cypress}/bin/Cypress
'';
}
@r-k-b
Copy link
Author

r-k-b commented Jan 21, 2021

Thanks to DamienCassou on the NixOS Discourse for the env vars hint, and rasendubi for the writable file fix!

@luka5
Copy link

luka5 commented Feb 4, 2021

Thanks for sharing this @r-k-b. For any one else, who suffered permission issues in ~/.config/Cypress before using these snippets: Make sure to delete the folder, before you run cypress with this fix. (I didn't ;) )

@ProofOfPizza
Copy link

Very nice, thank you! I tried to find out how/ where to fix it for firefox as well. I failed unfortunately.
Can you help either: How to fix it for firefox ? Or even better how to generalize a solution that would work for all browsers. ?
Any help is appreciated. I am out of my depths here.

@r-k-b
Copy link
Author

r-k-b commented Feb 15, 2021

@ProofOfPizza looks like Firefox needs the same trick applied to ./resources/app/packages/server/lib/browsers/utils.js; I've updated the overlay.

@ProofOfPizza
Copy link

Yes, once again thank you @r-k-b, that works!

@zeorin
Copy link

zeorin commented Mar 3, 2021

Thanks for this!

In my case export CYPRESS_RUN_BINARY=$(which Cypress) did not work (the variable was just blank), so I replaced it with export CYPRESS_RUN_BINARY=${pkgs.cypress}/bin/Cypress.

@zeorin
Copy link

zeorin commented Mar 4, 2021

In my case I was using Cypress 6.2.1, and I was getting read-only errors for a socket.io file. Instead of trying to find out where in Cypress's installation procedure that was being copied, and changing its permissions, I just find ~/.config/Cypress -exec chmod -v +w {} \; and it's working…

@r-k-b
Copy link
Author

r-k-b commented Mar 9, 2021

Ah, using the actual store path is a good idea, thanks zeorin!
I've updated the gist with that.

@jozuas
Copy link

jozuas commented Jun 1, 2021

Here's the overlay for Cypress 7.4.0. In my case, both Chromium and Firefox DevEdition work with this overlay.

# When Cypress starts, it copies some files into `~/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/`
# from the Nix Store, one of which it attempts to modify immediately after.
# As-is, this fails because the copied file keeps the read-only flag it had in
# the Store.
# Luckily, the code responsible is a plain text script that we can easily patch:
final: prev: {
  # This has only been tested against Cypress 7.4.0
  cypress = prev.cypress.overrideAttrs (oldAttrs: {
    installPhase = let
      matchForChrome = "yield utils_1.default.copyExtension(pathToExtension, extensionDest);";
      appendForChrome = "yield fs_1.fs.chmodAsync(extensionBg, 0o0644);";

      matchForFirefox = "copyExtension(pathToExtension, extensionDest)";
      replaceForFirefox = "copyExtension(pathToExtension, extensionDest).then(() => fs.chmodAsync(extensionBg, 0o0644))";
    in ''
      sed -i '/${matchForChrome}/a\${appendForChrome}' \
          ./resources/app/packages/server/lib/browsers/chrome.js

      sed -i 's/${matchForFirefox}/${replaceForFirefox}/' \
          ./resources/app/packages/server/lib/browsers/utils.js
    '' + oldAttrs.installPhase;
  });
}

@r-k-b
Copy link
Author

r-k-b commented Aug 13, 2021

On Cypress 7.5.0, noreferences' fix works, but I run into another error in interactive mode, only the second time I launch the browser in "open" mode:

EACCES: permission denied, unlink '/home/rkb/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/popup.html'

Running chmod u+rw -R ~/.config/Cypress/ lets me get past that error... not sure what to patch to avoid it in the first place.

@Diullei
Copy link

Diullei commented Feb 22, 2022

Here is the overlay variation that also pins the cypess version:

# When Cypress starts, it copies some files into `~/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/`
# from the Nix Store, one of which it attempts to modify immediately after.
# As-is, this fails because the copied file keeps the read-only flag it had in
# the Store.
# Luckily, the code responsible is a plain text script that we can easily patch:
final: prev: {
  cypress = prev.cypress.overrideAttrs (oldAttrs: rec {
    pname = "cypress";
    version = "9.5.0";

    src = prev.fetchzip {
      url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip";
      sha256 = "1sjkrx8yv187waly1namcks013apmr73jsr0fpyqyp93ddri8lvc";
    };

    installPhase =
      let
        matchForChrome = "yield utils_1.default.copyExtension(pathToExtension, extensionDest);";
        appendForChrome = "yield fs_1.fs.chmodAsync(extensionBg, 0o0644);";

        matchForFirefox = "copyExtension(pathToExtension, extensionDest)";
        replaceForFirefox = "copyExtension(pathToExtension, extensionDest).then(() => fs.chmodAsync(extensionBg, 0o0644))";
      in
      ''
        sed -i '/${matchForChrome}/a\${appendForChrome}' \
            ./resources/app/packages/server/lib/browsers/chrome.js

        sed -i 's/${matchForFirefox}/${replaceForFirefox}/' \
            ./resources/app/packages/server/lib/browsers/utils.js
      '' + oldAttrs.installPhase;
  });
}

In order to chage the cypress version you need to update the version and the sha256 variables.

NOTE: depending on the version it can happen that the installPhase will also need to be updated

@robintown
Copy link

Is there any reason this hasn't been upstreamed yet?

@r-k-b
Copy link
Author

r-k-b commented May 15, 2022

looks like the related issue in Cypress' repo is still open: cypress-io/cypress#18893

@marko911
Copy link

I followed all these steps but when I try to run cypress it errors out with :
qemu-x86_64: Could not open '/lib64/ld-linux-x86-64.so.2': No such file or directory

@vst
Copy link

vst commented Dec 15, 2022

For the record, I just upgraded from Cypress v10.11.0 to v12.1.0 and I had to drop entire installPhase.

So, as for cypress-overlay.nix, before:

## NOTE: This is a Nix overlay file taken and modified from:
##
## https://gist.github.com/r-k-b/2485f977b476aa3f76a47329ce7f9ad4
##
##
## When Cypress starts, it copies some files into
##
## ~/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/
##
## ... from the Nix Store, one of which it attempts to modify immediately
## after. As-is, this fails because the copied file keeps the
## read-only flag it had in the Store.
##
## Luckily, the code responsible is a plain text script that we can
## easily patch:
final: prev: {
  cypress = prev.cypress.overrideAttrs (oldAttrs: rec {
    pname = "cypress";
    version = "10.11.0";

    src = prev.fetchzip {
      url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip";
      sha256 = "06mi20jknc52i62l4lq2j1r9ahd7x2bm6vznc2v1flawh1vkvziv";
      ## Note: sha256 is computed via (note the version):
      ##
      ## nix-prefetch-url --unpack https://cdn.cypress.io/desktop/10.11.0/linux-x64/cypress.zip
    };

    installPhase =
      let
        matchForChrome = "yield utils_1.default.copyExtension(pathToExtension, extensionDest);";
        appendForChrome = "yield fs_1.fs.chmodAsync(extensionBg, 0o0644);";

        matchForFirefox = "copyExtension(pathToExtension, extensionDest)";
        replaceForFirefox = "copyExtension(pathToExtension, extensionDest).then(() => fs.chmodAsync(extensionBg, 0o0644))";
      in
      ''
        sed -i '/${matchForChrome}/a\${appendForChrome}' ./resources/app/packages/server/lib/browsers/chrome.js
        sed -i 's/${matchForFirefox}/${replaceForFirefox}/' ./resources/app/packages/server/lib/browsers/utils.js
      '' + oldAttrs.installPhase;
  });
}

... and after:

## NOTE: This is a Nix overlay file taken and modified from:
##
## https://gist.github.com/r-k-b/2485f977b476aa3f76a47329ce7f9ad4
##
##
## When Cypress starts, it copies some files into
##
## ~/.config/Cypress/cy/production/browsers/chrome-stable/interactive/CypressExtension/
##
## ... from the Nix Store, one of which it attempts to modify immediately
## after. As-is, this fails because the copied file keeps the
## read-only flag it had in the Store.
##
## Luckily, the code responsible is a plain text script that we can
## easily patch:
final: prev: {
  cypress = prev.cypress.overrideAttrs (oldAttrs: rec {
    pname = "cypress";
    version = "12.1.0";

    src = prev.fetchzip {
      url = "https://cdn.cypress.io/desktop/${version}/linux-x64/cypress.zip";
      sha256 = "1jbjsgb3msjlx0y6wjvb99n3v009sc0nq19grlad57f2p5y0iy09";
      ## Note: sha256 is computed via (note the version):
      ##
      ## nix-prefetch-url --unpack https://cdn.cypress.io/desktop/12.1.0/linux-x64/cypress.zip
    };
  });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment