Closed rbokel closed 5 years ago
Hi @rbokel, currently, sending flags through to Electron does not work. There is an issue here to support this: https://github.com/cypress-io/cypress/issues/1519 I will close this issue as duplicate.
I also created a new issue in our docs to document that passing flags to electron is not currently supported here: {{LINK TO ISSUE}}. Our documentation is open source and contributions are welcome.
Hi @jennifer-shehane, apart from me passing the options, there would also be the possibility for cypress to activate the fake-device by itself, similar to what it does with many other browser features.
Otherwise all tests that involve a webcam will fail. Maybe i should rephrase this ticket ?
Yes, I can see this being a valuable feature. I will reopen and rephrase the title. It would be helpful if you could rephrase your original ticket to specify support for these and also any details about how this ends up working - when faking the device.
Ok, thanks @jennifer-shehane Rephrased it and added a minimal example
I've spent some time investigating this issue today on Cypress 3.1.4.
Reproducible repo: https://github.com/jennifer-shehane/webcam-tests
Upon attempting to test a webcam, the first hurdle is being prompted by this dialog:
This prompt is discarded by adding the --use-fake-ui-for-media-stream
flag.
--use-fake-ui-for-media-stream
Bypass the media stream infobar by selecting the default device for media streams (e.g. WebRTC). Works with--use-fake-device-for-media-stream
.
Or as WebRTC's Testing guides plainly puts it:
--use-fake-ui-for-media-stream
avoids the need to grant camera/microphone permissions.
This should clearly be implemented by default into Cypress.
Upon enabling the --use-fake-ui-for-media-stream
and running tests again, the live video feed is presented, which is like "Smile, you're on camera!" 😂
This is creepy and likely would not pass in a CI environment without the proper environment set up on the machine to handle a cameras/microphone.
So, we want to be able to have some 'fake' video to test the functionality. There are 2 options here:
--use-fake-device-for-media-stream
feeds a test pattern to getUserMedia()
instead of live camera input.--use-file-for-fake-video-capture=path/to/file.y4m
feeds a Y4M test file to getUserMedia()
instead of live camera input.When passing --use-fake-device-for-media-stream
, a fake video steam is used as shown below in this very low frame rate gif:
When passing --use-file-for-fake-video-capture
, there are some requirements outline in Chromium source comments:
Used for testing the video capture pipeline when no real hardware is available. The supported file formats are YUV4MPEG2 (a.k.a. Y4M) and MJPEG/JPEG. YUV4MPEG2 is a minimal container with a series of uncompressed video only frames, see the link http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 for more information on the file format. Several restrictions and notes apply, see the implementation file.
Example Y4M videos can be found in http://media.xiph.org/video/derf. Example MJPEG videos can be found in
media/data/test/bear.mjpeg
.Restrictions: Y4M videos should have
.y4m
file extension and MJPEG videos should have.mjpeg
file extension.
Passing the --use-file-for-fake-video-capture
flag with the absolute or relative path of the Y4M file looks like this (again in my very low frame rate gif - looks better when running).
Note that in order for the provided video file to work, the previous 2 flags must exist for it to work, so now we have these arguments:
module.exports = (on, config) => {
on('before:browser:launch', (browser = {}, args) => {
// args.push('--use-fake-device-for-media-stream')
if (browser.name === 'chrome') {
args.push('--use-fake-ui-for-media-stream')
args.push('--use-fake-device-for-media-stream')
args.push('--use-file-for-fake-video-capture=cypress/fixtures/akiyo_cif.y4m')
}
return args
})
}
The WebRTC testing doc also mentions these flags for testing:
--allow-file-access-from-files
allows getUserMedia() to be called fromfile://
URLs.--disable-gesture-requirement-for-media-playback
removes the need to tap a<video>
element to start it playing on Android.
I'm going to err on the side of not adding these, because I'm not sure why they would be needed. But please open a new issue if you need one of these flags.
--use-fake-ui-for-media-stream
to Cypress default flags--use-fake-device-for-media-stream
to Cypress default flags--use-file-for-fake-video-capture
to the browser launch API works properly.Resources:
Hey @jennifer-shehane I cloned your example repo but the y4m video doesn't show :( what version of chrome did you use?
UPDATE: I tested on macOS (High Sierra 10.13.6 / Chrome 71) and the example works very well because the path, so in Windows is a bit different.
Just change the path like this:
--use-file-for-fake-video-capture=c:\\path\\to\\video\\akiyo_cif.y4m
@Darkensses Thanks for providing a Windows example!
Released in 3.1.5
.
wow, that was fast! Thanks 👍
@jennifer-shehane Hi I have been writing some tests to verify ID verification process during a specific user journey. There are 2 parts to this process - 1. is it to upload a file for example passport and 2. is to capture/upload a selfie image. The problem i am encountering with cypress is that it switches ON the fake camera by default and i am struggling to upload an image or to send out a video file(which I dont want to do) I just want to basically skip this fake camera input and use the upload function. Is there any way I can do this by passing something like "--disable--fake-video-capture". If you need any more info let me know.
@nkrishna79 You can upload your own file, instead of the fake file by following these instructions: https://docs.cypress.io/api/plugins/browser-launch-api.html#Use-fake-video-for-webcam-testing
But, basically we pass the --use-fake-ui-for-media-stream
and --use-fake-device-for-media-stream
flags if you want to play with removing those in the before:browser:launch
I linked you to.
@jennifer-shehane So do you think if I use arguments something along the lines of args.push('--disable-fake-device-for-media-stream') args.push('--disable-fake-ui-for-media-stream') would I still be able to disable the fake camera input? update:
If i pass those arguments to disable it - its not disabling the fake camera input. I tried removing it too but but no luck cypress still forces me to use the fake camera. basically i need a mechanism to disable it. Thats all.
No, these args do not exist within Chrome flags. args
is an array of flags sent to Chrome containing --use-fake-ui-for-media-stream
and --use-fake-device-for-media-stream
, so you need to remove those 2 items from the args. So, use JavaScript to find those 2 arguments and remove them from the args
array before passing them along.
Right ok. let me give it a try. Thanks @jennifer-shehane
No, these args do not exist within Chrome flags.
args
is an array of flags sent to Chrome containing--use-fake-ui-for-media-stream
and--use-fake-device-for-media-stream
, so you need to remove those 2 items from the args. So, use JavaScript to find those 2 arguments and remove them from theargs
array before passing them along.
@jennifer-shehane I tried some methods to disable it. But couldnt get around on how to do this via JavaScript. Would you be able to show me a sample step on how to do this via JS. Thanks
@jennifer-shehane I can see that its been passed as flag to chrome from this script https://github.com/cypress-io/cypress/blob/develop/packages/server/lib/browsers/chrome.coffee#L21
But how/where can I comment out this line in order for me to be able to not use the fake camera ui?
Solution for providing mjpeg file on Windows (MJPEG has much better compression than y4m)
ffmpeg -i input.mp4 output.mjpeg
cypress/plugins
cypress/plugins/index.js
add the following snippet to module.exports
on("before:browser:launch", (browser = {}, args) => {
if (browser.name === "chrome") {
args.push("--use-fake-ui-for-media-stream");
args.push("--use-fake-device-for-media-stream");
args.push(`--use-file-for-fake-video-capture=${__dirname}\\out.mjpeg`);
}
return args;
});
Using __dirname
makes sure we get the absolute path Windows needs
Original question: Hi, I have made with work with a .y4m file, however, when using a .mjpeg file encoded from an .mp4, it fails. Are there any other requirements for the .mjpeg format apart from the one stated? (must end with .mjpeg, which it already does) Thanks.
@JouzaLoL I tried your solution (adapted to GNU/Linux) and Cypress doesn't show the video on my test suite.
@jennifer-shehane
Example MJPEG videos can be found in media/data/test/bear.mjpeg.
The media/data
directory is gone from there and it seems that the example videos were also removed.
I've tried your example (on cypress@4.3.0
) after following https://docs.cypress.io/api/plugins/browser-launch-api.html#Use-fake-video-for-webcam-testing and none of the videos I tried, were shown on the webcam view of the app (with both --use-fake-...
and the --use-file-for-fake-video-capture
flags being pushed to launchOptions.args
), what could be causing that?
Is it possible to see actual fake video play-back in electron?
@jennifer-shehane similar question like above but Im trying to use fake video but in firefox.
in selenium there will be smth like
options.addPreference("media.navigator.streams.fake", true);
@jennifer-shehane similar question like above but Im trying to use fake video but in firefox. in selenium there will be smth like
options.addPreference("media.navigator.streams.fake", true);
However, firefox doesn't support an injection video like y4m or another format: https://github.com/mozilla/geckodriver/issues/1429
I'm also having trouble making a custom video show up. I'm on WSL2 using the Linux path format: launchOptions.args.push('--use-file-for-fake-video-capture=cypress/fixtures/folder/file.mjpeg')
. I'm getting the default green video.
In fact I can mistype the file name and get the same result. It would be really helpful to get an explicit error if the referenced file is not found/recognized. Hard to figure out what the issue might be otherwise.
I'm also having trouble making a custom video show up. I'm on WSL2 using the Linux path format:
launchOptions.args.push('--use-file-for-fake-video-capture=cypress/fixtures/folder/file.mjpeg')
. I'm getting the default green video.
hey @thisismydesign I recommend you using a y4m video. When the video file is not found/recognized, chrome display the 'green video' by default. Please try with a y4m file :)
@Darkensses Thanks, in the end, y4m didn't work for me, and actually mjpeg did. As described in https://github.com/cypress-io/cypress/issues/9562
Is there a way to remove this arg while launching chrome? https://github.com/cypress-io/cypress/blob/develop/packages/server/lib/browsers/chrome.ts#L100
@vikrant-lh You can modify the browser launch args. See https://on.cypress.io/browser-launch-api#Modify-browser-launch-arguments-preferences-and-extensions
@jennifer-shehane Thanks, I got a workaround, I've edited the array to remove un-required flags :) thanks :)
Current behavior:
My client code is using the webcam. On ci there is no webcam. For Chrome and Chromium i can fake the webcam using the code below in my
plugins/index.js
This makes my tests pass.
On electron my test fails and i cannot seem to pass these options.
On a system without webcam with chrome and the options set as explained above, the test succeeds.
On a system without webcam with electron the test fails.
Desired behavior:
Electron should use the fake-device and fake-ui by default to make tests pass, that require a webcam.
Versions
cypress: 3.1.0 ubuntu 18.04.1 lts chrome 70
Reproducible Example