Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cy.exec fails on windows #789

Open
dwelle opened this issue Oct 23, 2017 · 55 comments
Open

cy.exec fails on windows #789

dwelle opened this issue Oct 23, 2017 · 55 comments
Labels
E2E Issue related to end-to-end testing OS: windows prevent-stale mark an issue so it is ignored by stale[bot] stage: ready for work The issue is reproducible and in scope Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. type: bug

Comments

@dwelle
Copy link

dwelle commented Oct 23, 2017

Current behavior:

image

From the bug, the path seems mangled:

  1. first part is UNIXy /c/Program
  2. There's a : inserted into the (Program Files) folder name for some reason
  3. 2nd half is in windows format (backslashes)

How to reproduce:

cy.exec('echo 42');

Additional Info (images, stack traces, etc)

On my machine is installed (and in env variables) the git-for-windows bash, which is the bash the cypress is trying to invoke.

  • Operating System: Windows 7/x64
  • Cypress Version: 1.0.2
  • Browser Version: canary 64
@bahmutov
Copy link
Contributor

Hmm, I wonder if the git-for-windows is confusing shell read from Cypress. Will need to install and test it.

@bahmutov bahmutov self-assigned this Oct 24, 2017
@bahmutov bahmutov added the stage: needs investigating Someone from Cypress needs to look at this label Oct 24, 2017
@keithernet
Copy link

Hello,

I am also having an issue running exec in Windows 10. My git bash install path is C:\dev-tools\Git\usr\bin. When I exec cypress logs:
cypress:server shell C:\dev-tools\Git\usr\bin\bash.exe profile undefined +4ms cypress:server cy.exec found shell C:\dev-tools\Git\usr\bin\bash.exe +1ms cypress:server and is running command: echo +1ms

The command fails with Stderr: /usr/bin/bash: /s: No such file or directory

I'm not sure if this is an issue with my git-bash install or the way cypress is calling it. Any help would be greatly appreciated.

@GuyBransgrove
Copy link

I haven't got a solution for this (yet) but I do know what the problem is.

image
(https://github.com/sindresorhus/execa/blob/master/index.js)

Basically the above section in the dependency "execa" is the problem. If your platform is windows it makes the assumption that your shell is cmd and it structures the resulting command as follows:

C:\\ProgramFiles\\Git\\usr\\bin\\bash.exe /s /c "source undefined > /dev/null 2>&1; echo foo"
(Yes, that is ProgramFiles with no spaces. I was trying to work around the original issue.)

As you can see the flags /s /c make sense in cmd, but bash sees them as file paths and we get the error we are all seeing. In line 89 you can see what the args variable should actually be set to when you shell is bash.

@jennifer-shehane
Copy link
Member

@GuyBransgrove Thanks for looking into this and opening the issue with execa - hopefully they get a fix in and we can update the package.

@jennifer-shehane jennifer-shehane added stage: awaiting external fix A 3rd party bug in Cypress - awaiting release and removed stage: needs investigating Someone from Cypress needs to look at this labels Aug 10, 2018
@jennifer-shehane jennifer-shehane added stage: needs investigating Someone from Cypress needs to look at this and removed stage: awaiting external fix A 3rd party bug in Cypress - awaiting release labels Aug 27, 2018
@jennifer-shehane
Copy link
Member

jennifer-shehane commented Aug 27, 2018

execa has decided to not offer support for cmd.exe-incompatible shells, so this looks like something we would have to manually support.

@Sandy-Garrido
Copy link

execa has decided to not offer support for cmd.exe-incompatible shells, so this looks like something we would have to manually support.

That's great news. Is there a solution as of yet to have this working at all on windows at all? I seem to be getting this error regardless of the shell used being on windows

@Vandivier
Copy link

How about using ShellJS?

@jennifer-shehane jennifer-shehane added stage: ready for work The issue is reproducible and in scope type: bug and removed stage: needs investigating Someone from Cypress needs to look at this labels Feb 5, 2019
@Saibamen
Copy link
Contributor

This same issue: #1034

@selvex
Copy link

selvex commented Aug 20, 2019

Found a solution that does the trick for now.
I'm using cypress.task to start a task which I define in the plugins file. There, I import shell-exec, a npm package that also supports windows. Since I only need a single command for now, this works fine.

Sharing full example for clearness.
cypress/plugins/index.js

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
require('dotenv').config();
const shell = require('shell-exec');
module.exports = (on, config) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
  on('task', {
    'env': () => {
      return new Promise(resolve => {
        resolve(process.env);
      });
    },
    // relevant part
    'db:clean': () => {
      return shell('npx gulp db:clean');
    }
  })
};

And in a test:

it('can register a new account', () => {
      cy.task('db:clean');
      
      cy.visit('/register');
});

It returns a promise, so it is then-able. However cypress waits for the completion out-of-the-box.

Hope that helps.

@flotwig
Copy link
Contributor

flotwig commented Dec 27, 2019

execa has decided to not offer support for cmd.exe-incompatible shells, so this looks like something we would have to manually support.

The reason this issue occurs is because Git Bash sets the SHELL environment variable, which Cypress then tries to use with execa.

Since the docs don't say anything about what shell should be used in cy.exec, and there's no option to supply a custom shell, I think we should just short-circuit the shell detection code to always use cmd.exe on Windows until people ask for support for other shells.

That would mean moving lines 88-92 of this getShell function to the top:

const getShell = function (shell) {
if (shell) {
return Promise.resolve(shell)
}
// if we didn't get a shell such
// as when we're in docker
let s = process.env.SHELL
if (s) {
return Promise.resolve(s)
}
if (isWindows()) {
log('use default shell on Windows')
return Promise.resolve()
}
return findBash()
}

Tested and this fixes the issue on Windows 10. Don't believe it would change existing behavior, since the current behavior is "use cmd.exe or fail".

@dwelle
Copy link
Author

dwelle commented Dec 27, 2019

That would mean we won't be able to use UNIX shell programs, which means that cross-platform tests written for UNIX target would stop working.

Is this issue still outstanding though? It works for me at the moment (I've also tried using execa directly, and it works, too). Though, some things changed, such as my SHELL path not containing spaces as it did in OP --- but weren't the main issue that execa passed cmd.exe switches even to the bash shell? It seems that's no longer an issue.

@flotwig
Copy link
Contributor

flotwig commented Dec 27, 2019

That would mean we won't be able to use UNIX shell programs, which means that cross-platform tests written for UNIX target would stop working.

Would it though? I only say that because AFAIK, currently, you cannot launch Cypress from a non-cmd.exe shell and then successfully use cy.exec, at all, in any way. Any command will give you the error from the OP. So tests that would break in the way you're describing are already broken today, and I'd assume that tests that pass today are most likely being launched through cmd.exe.

The change I'm proposing would make cy.exec behave as if Cypress is always launched from cmd.exe on Windows, which will make cy.exec work in non-cmd.exe shells.

Let me know if this is mistaken or you see a breaking change with this.

Is this issue still outstanding though? It works for me at the moment (I've also tried using execa directly, and it works, too). Though, some things changed, such as my SHELL path not containing spaces as it did in OP --- but weren't the main issue that execa passed cmd.exe switches even to the bash shell? It seems that's no longer an issue .

I just experienced the issue in CI using bash.exe, and switching the CI step to use cmd.exe with SHELL empty fixed it:

@dwelle
Copy link
Author

dwelle commented Dec 27, 2019

Would it though? I only say that because AFAIK, currently, you cannot launch Cypress from a non-cmd.exe shell and then successfully use cy.exec, at all, in any way.

Interesting. You're right, I've just tested. Previously it worked for me because I've run the test from the vscode terminal (which I have configured to use bash.exe, though) --- but running the test directly from cmd.exe or bash.exe results in the error.

Weirdly enough, it seems that I have two bash.exe executables on my system:

  1. C:\Windows\System32\cmd.exe --- this is used by vscode terminal (and since it contains no spaces, it works).
  2. C:\Program Files\Git\usr\bin\bash.exe --- this is the default shell (weirdly, echo $SHELL shows /usr/bin/bash, which isn't a valid absolute path. It seems the path is relative to C:\Program Files\Git\).

That being said, it seems this error comes down to improperly handling the path (not sure whose fault that is, but I believe it's Cypress').

cy.exec seems to use (2), but handles it in such a way that it results in the OP error of /c/Program: Files\Git\usr\bin\bash.exe: No such file or directory. I believe if we solve that, this issue would be resolved (since the upstream issue in execa seems to no longer exist).

@jaffrepaul
Copy link
Contributor

jaffrepaul commented Jun 3, 2021

I see that @jennifer-shehane commented in February about capturing errors with the current Cypress version and we have some confirmation (v5.10 - v6.5.0) with varying degrees of workaround effort included.

Just curious, @Tobbe which version you are currently running and if you still have this issue in 7.4.0? I would assume yes given the nature of the issue thus far. The outstanding issue may just be deciding which path to take.

adding @flotwig & @bahmutov for good measure

@Tobbe
Copy link

Tobbe commented Jun 3, 2021

@jaffrepaul Thanks for giving this issue some attention. I gave up on trying to get this to work for a while, but I could never truly let it go, I keep thinking about it :) Thanks to your nudge I'll try to get the project spun up locally again and give it another go. Hopefully I can report back with answers to your questions tomorrow

@Tobbe
Copy link

Tobbe commented Jun 6, 2021

@jaffrepaul Finally got around to try this again.

I can confirm we're still seeing the same issue in 7.4.0

image

image

@ivanAndCode
Copy link

ivanAndCode commented Aug 24, 2021

I also bumped into this issue with Cypress 8.0.0.
Used a workaround provided by @Josef37 here
Here's my slightly modified code:
cypress.json

...
    "env": {
      "bash": "C:\\Program Files\\Git\\bin\\bash.exe",
      "comSpec": "C:\\Windows\\system32\\cmd.exe",

helper.ts:

export function fetchSecrets() {
  cy.log(`Platform: ${Cypress.platform}`)
  cy.log(`Architecture: ${Cypress.arch}`)

  const command = 'pathToScript/fetch.secrets.sh secretName secretKeyvault';

 if (Cypress.platform !== 'win32') {
    cy.exec(command);
  } else {
    // This is a workaround against cy.exec not working on windows machine
    // https://github.com/cypress-io/cypress/issues/789
    // To make this code work you need to setup 2 cypress env variables
    // - bash (pointing to the bash shell executable on your machine)
    // - comSpec (pointing to cmd.exe on your machine)
    cy.log('Bash path: ' + Cypress.env('bash'))
    cy.log('cmd.exe path: ' + Cypress.env('comSpec'))

    const sh = `"${Cypress.env('bash')}" --login -c`;
    const fullCommand = `${sh} "${command}"`
    //for some reason cypress cannot find shell on the first try so it throws
    //this is a retry hack allowing cypress to gracefully deal with error
    executeCypressCommand(fullCommand, false)
    executeCypressCommand(fullCommand, true)
  }

function executeCypressCommand(command: string, failOnError: boolean = true) {
  cy.exec(command, {env: {SHELL: Cypress.env('comSpec')}, failOnNonZeroExit: failOnError}).then(result => {
    cy.log('Exit code: ' + result.code.toString())
    if (result.stdout.toString().length > 0) {
      cy.log('Stdout: ' + result.stdout.toString())
    }
    if (result.stderr.toString().length > 0) {
      cy.log('Stderr: ' + result.stderr.toString())
    }
  })
}

/support/index.ts

import {fetchSecrets} from './helpers/helper'

before(() => {
  fetchSecrets()
})

I think there might be a room for improvement/optimisation, but I haven't explored it yet (hashtag worksonmymachinenow 🤣 ). Will try to update my comment if I will end up spending more time on it.
Hope this will help someone :)

Update: Weirdly it fails on the first run... I can see what you meant now. If you have cypress open and refresh it, everything works. When you try to run it in a cicd fashion, this solution fails:( I have added a retry into the example above to fix this problem.

@clazette
Copy link

clazette commented Oct 22, 2021

Switch your default terminal, in VS Code, from Bash to PowerShell and the problem is solved.

@amadeogallardo
Copy link

Upgraded to Cypress 9.2.0 and the error is still present.

@clazette
Copy link

clazette commented Dec 30, 2021

You switched to PowerShell and you're still having the issue?

@amadeogallardo
Copy link

amadeogallardo commented Dec 30, 2021

To clarify: the error still happens when running Cypress from a Bash terminal in VS Code. It doesn't happen when using either CMD or PowerShell. But, I would assume that any terminal should work.

@clazette
Copy link

There is an issue when using Bash. Yes, it needs to be resolved but switching to CMD or PowerShell solves the issue and you can do what you need to do, yes? I'm not sure why you downvoted my response. It solved the issue and you can proceed, no? Did I not provide helpful information so that someone may avoid hours of screwing with something before they realize that it's something specific to Bash?

@amadeogallardo
Copy link

Although you provided a valid workaround (which I was already aware of) the problem is not really "solved". No animosity, just reporting back that this issue still happens on the latest version.

@clazette
Copy link

I wasn't attempting to solve the issue for Cypress. I was attempting to provide information that would, hopefully, prevent others from wasting hours of their lives messing with this issue not realizing that it was something specific to Bash. Anyway, whatever, glad you know about the workaround.

@jb1mc
Copy link

jb1mc commented Jun 24, 2022

The issue is present with Cypress v9.4.1 when using Git Bash with VS Code.

image

@moishinetzer
Copy link

moishinetzer commented Jul 21, 2022

The issue is STILL present with Cypress v10.3.0 when using Git Bash with VS Code on windows

@strowk
Copy link

strowk commented Sep 30, 2022

Had this, fiexed by resinstalling Git Bash in "C:/Git" rather than "C:/Program Files/Git". Took some additional effort to make vscode understand where shell is now installed, but it all worked out in the end.

@gustawx
Copy link

gustawx commented Oct 13, 2022

@strowk worked for me as well, thanks for tip! Maybe it's about a space character in the path :/

@ddfridley
Copy link

ddfridley commented Oct 21, 2022

This is still a problem with 10.10.0, but some how it has changed from no space a while back, to colon and then space.

Stderr:
/c/Program: Files\Git\usr\bin\bash.exe: No such file or directory

I see all these work arounds, but for open source projects we really need the repo to just install and run.
The root of the problem seems to be something inserting a ": " in the path. How do we fix that!

I'm using git bash from vs code.

One other observation, from the bash terminal in vscode the path to bash is:

$ which bash
/usr/bin/bash

So shouldn't cy.exec be using the environment variables from where it is being run from?

@nagash77 nagash77 added the prevent-stale mark an issue so it is ignored by stale[bot] label Apr 3, 2023
@DJSdev
Copy link
Contributor

DJSdev commented Apr 7, 2023

Just started running into this on Cypress 12.7. The cy.exec() has been working for weeks on this version, but now all of a sudden I'm getting the exact same error that was described years ago. I haven't reinstalled git or anything. Nothing on my system has changed as far as I know. Just all of a sudden can't execute anything residing in program files.

@MikeMcC399
Copy link
Contributor

I noticed running the example cypress-io/cypress-example-kitchensink on Microsoft Windows 11 with an out-of-the-box configuration, that the test cypress/e2e/2-advanced-examples/misc.cy.js with cy.exec('echo Jane Lane') succeeds in a cmd terminal window and fails in a git bash terminal window.

That should probably be documented somewhere.

@nagash77 nagash77 added E2E Issue related to end-to-end testing Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. and removed routed-to-e2e labels Apr 19, 2023
@nikola-ignjatovic
Copy link

It still doesn't work well. I managed to fix it temporarily by switching to Powershell terminal in Webstorm. It worked for a week or two and after that it started to not work again. My friend has the exact same tests but he is running them on Linux and everything works just fine there.

@KhushalGupta
Copy link

KhushalGupta commented Sep 15, 2023

I am facing the same issue on Cypress 12.13.0, where cy. exec(command) fails on Github Action runs on ubuntu machine, but works locally from Machine Terminal in MAC OS.

@B34v0n
Copy link

B34v0n commented Feb 19, 2024

I'm facing the same issue on Cypress 13.6.4. When can this be solved?

@MikeMcC399
Copy link
Contributor

MikeMcC399 commented Feb 19, 2024

@B34v0n

I'm facing the same issue on Cypress 13.6.4. When can this be solved?

Which version of Windows and which shell / terminal window application are you using?

Running https://github.com/cypress-io/cypress-example-kitchensink/blob/master/cypress/e2e/2-advanced-examples/misc.cy.js om Windows 11, I found that cy.exec() failed in Git Bash, and ran successfully in Command Prompt and PowerShell.

@B34v0n
Copy link

B34v0n commented Feb 19, 2024

@MikeMcC399

I'm using Windows 11 22H2 with Git Bash.
I can't use PowerShell, because it is a work-computer and it's locked.

The whole company uses the git-bash and no one uses the normal cmd (for nvm for example). So I need it to work with git-bash on Windows.

@MikeMcC399
Copy link
Contributor

@B34v0n

Thanks for confirming that you are using Git Bash where it's a known issue. Looking back at the history, this issue has been open for over 6 years and different people have suggested different workarounds and solutions, although none have made their way into Cypress as a standard resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E2E Issue related to end-to-end testing OS: windows prevent-stale mark an issue so it is ignored by stale[bot] stage: ready for work The issue is reproducible and in scope Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. type: bug
Projects
None yet
Development

No branches or pull requests