Is there a way to capture an image via Selenium when running the test on a Jenkins server?

61 Views Asked by At

I've automated a web app that opens up the camera and takes a photo. On my local machine the Selenium script executes and captures the photo (running in headless mode). However, when I run the script via Jenkins server, no photo is being captured. The automation script is written in Java 11. I'm using Firefox as the browser. My Selenium is version: '4.1.2'. Before launching the browser I've granted access to the camera via a profile as below:

// set the profile to allow camera access
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("media.navigator.permission.disabled", true);
firefoxOptions.setProfile(profile);
System.setProperty(systemProperty, driverPath);
webDriver = new FirefoxDriver(firefoxOptions);

Logic is telling me this is because the Jenkins server does not have a camera. If that is the case, is there a way to fake a camera? Thanks for any pointers.camera on jenkins server

Opening the camera and taking the photo are straightforward, snippet:

    @Step ("capture photo")
    public ConfirmPhotoPO capturePhoto(){
        SeleniumWaitUtil.waitUntilElementToBeClickable(captureBtn);
        // try capture a photo, and check if we can upload
        clickElement(captureBtn);
        return new ConfirmPhotoPO();
    }

The application is an Angular web app. With the above, the expectation is that the camera page is opened and the button clicked and the photo captured. However, only the camera page is opened (which has the capture photo button), but no photo is being captured. Camera page captured on test failure on the Jenkins server

2

There are 2 best solutions below

1
Hiruni Dahanayake On

The problem may be the camera having nothing to capture. Give some mock camera inputs that can be captured at this line -

clickElement(captureBtn);

Also make sure that the virtual environment can handle camera input emulation.

0
Tinashe Chinyanga On

The solution to this is to enable a fake video stream which is an config. available as a FireFox option. I added the below preference to a FireFox profile

"media.navigator.streams.fake", true

:

FirefoxOptions firefoxOptions = new FireFoxOptions();
// create a FireFox profile
FirefoxProfile profile = new FirefoxProfile();
// use the profile to enable access to the camera when the browser starts
profile.setPreference("media.navigator.permission.disabled", true);
// open a fake video stream that will allow the photo to be captured
profile.setPreference("media.navigator.streams.fake", true);
firefoxOptions.setProfile(profile);

With the setup above, the browser will start, grant access to the camera using the profile specified and when the camera is opened, a fake video stream is generated which is captured by the camera from the application under test.