Open dwelle opened 6 years ago
Hmm, I wonder if the git-for-windows
is confusing shell read from Cypress. Will need to install and test it.
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.
I haven't got a solution for this (yet) but I do know what the problem is.
(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.
@GuyBransgrove Thanks for looking into this and opening the issue with execa - hopefully they get a fix in and we can update the package.
execa has decided to not offer support for cmd.exe-incompatible shells, so this looks like something we would have to manually support.
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
This same issue: #1034
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.
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:
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".
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.
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 passedcmd.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:
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:
C:\Windows\System32\cmd.exe
--- this is used by vscode terminal (and since it contains no spaces, it works).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).
Agreed, that's probably the preferred approach if execa
will indeed work with bash.exe
.
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).
Is this supposed to be a path to a bash.exe
executable? :stuck_out_tongue:
Wha..
It's not, I misread it :). But I'm indeed using bash.exe
, it's just configured via settings.json
(and isn't reflected in the vscode settings view, from which I blindly copied it). WTBS, the path again points to the Git path:
"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe",
Thus, it still contains the space. Why does Cypress handle it correctly, when invoked from vscode terminal, though?
What is the value of the SHELL
environment variable in each environment?
Not sure how to figure that out on windows (maybe looking it up in registry?) except echo $SHELL
, which feels not very authoritative. But it reports /usr/bin/bash
when executed both from vscode terminal, and bash.exe.
Googling, it seems that echo %SHELL%
should work in cmd.exe, but it seems this env variable is only set within the bash.exe
process, because echoing it from cmd.exe
shows nothing (which suggests it doesn't exist).
Cool, that sounds right. Strange, in that case I have no idea why it works in VScode but not outside it. There's a lot of logic in the shell.js
file that needs to be unpacked...
For intelliJ https://www.jetbrains.com/help/idea/settings-tools-terminal.html choose your terminal as cmd for windows .
For VS Code : Check the settings - Terminal › External: Windows Exec Customizes which terminal to run on Windows. C:\windows\System32\cmd.exe
Hope this helps
I was using git bash to run cypress, when i changed to windows powershell it worked for me
Is there any update to this issue or any workaround? I can't seem to get cy.exec
to work on Windows at all, even via VSCode or cmd. Makes it pretty difficult to use Cypress at the moment sadly.
EDIT: @selvex's solution does work for me as well, I did something wrong when I tried it the first time. This is a reasonable workaround for the moment, but obviously it would be great for cy.exec
to work on Windows too.
I am running into the same situation and was wondering if cy.exec
works on Windows....
Is this still an issue? Can anyone provide the code and the error they see when running a failing cy.exec() command in our current version?
I am not sure because I switched to an Ubuntu operating system.
I saw this issue two days ago. execa has solved the issue on their side with this PR: https://github.com/sindresorhus/execa/pull/181
Not sure what version of cypress we're on, will check and report back
Upgraded to 6.4.0 and I still get the same error
(Oops, copied the error from a different line, but the error is the same on all lines that call cy.exec
)
This issue still reproduces. I ran into it while working off a clone of this repo on a windows machine.
On 6.5.0 I can confirm that
I guess the question is, what do we want.
I think it would be nice to be able to change cy.exec terminal (ex in cypress.json and cypress.env.json) to be able to choose between cmd, powershell, sh and git-bash at least. I think it is fair to have a default value. This value, instead of being based on my computer could be powershell core has it is now a standard on both linux and windows.
So I would propose:
It's a spec proposition, so please feel free to argue with it :).
A workaround I currently use. Just utilize Windows' command line to invoke Git Bash, since we get those Windows flags from execa
.
// Setup 'bash' and 'comSpec' [environment variables](https://docs.cypress.io/guides/guides/environment-variables)
const command = 'yarn run seed';
if (Cypress.platform !== 'win32') {
cy.exec(command);
} else {
// This is a hack!
const sh = `"${Cypress.env('bash')}" --login -i -c`;
cy.exec(`${sh} "${command}"`, { env: { SHELL: Cypress.env('comSpec') } });
}
Weirdly it fails on the first run...
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
@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
@jaffrepaul Finally got around to try this again.
I can confirm we're still seeing the same issue in 7.4.0
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.
Switch your default terminal, in VS Code, from Bash to PowerShell and the problem is solved.
Upgraded to Cypress 9.2.0
and the error is still present.
You switched to PowerShell and you're still having the issue?
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.
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?
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.
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.
The issue is present with Cypress v9.4.1 when using Git Bash with VS Code.
The issue is STILL present with Cypress v10.3.0 when using Git Bash with VS Code on windows
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.
@strowk worked for me as well, thanks for tip! Maybe it's about a space character in the path :/
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?
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.
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.
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.
Current behavior:
From the bug, the path seems mangled:
/c/Program
:
inserted into the (Program Files
) folder name for some reasonHow to reproduce:
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.