Home video for Selenium aka WebDriver. Or than recording a screen if you have java, broken tests and a little time

At work, we decided to automate tests for several of our web applications. And besides the information when the tests fell, I also wanted to see how the page looked at this sad moment.



I have not picked up checkers and Selenium for a long time, so I had to dig a little on the Internet and look for what smart people do in this situation. The solution that suited me in the end brought together several technologies: Java + Selenium + Junit + Allure + ffmpeg + VideoRecorder (by Pirogov). But since I still honestly dug, trying to find the best solution to the problem, there were several more alternative and simpler ways to mine - how you can take a screen shot.



Since the information found is scattered all over the Internet, I think it would be nice to have some concise synopsis in one place. In fact, the article turned out as a small introduction for beginners. Those who are concerned with the same problem - to see with their eyes what was or did not exist when the autotests threw out the red flag.



Let's see what we are being asked to do.



How to take a screenshot of the screen



The very first option that can be thought of for our problem is to take screenshots of the screen. Those. guess the moment when the test will fail and get a picture. You can generally take a screenshot for each action. Or take a screenshot at a certain frequency (for example, once every half a second).



Method 1. Selenium



Since many tests are written in Selenium / WebDriver, it would be reasonable to use its methods. For instance:



WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com/"); 
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\tmp\\screenshot.png"));


Method 2. Selenide The



second way is to use wrappers for Selenium, for example Selenide. This framework simplifies the work with the driver and, among other things, makes screenshots automatically when an error occurs. By default, screenshots are stored in the “test-result / reports” folder.



Method 3. java.awt.Robot



The next method is to use a generally standard Java class (since version 1.3) to work directly with the operating system. A small example of how similar code might look:



BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); 
ImageIO.write(image, "png", new File("/screenshot.png"));


Method 4. Using external programs



Find a program that takes screenshots and use its API. Of course, there is such a method, but I did not even dig in this direction.



Method 5. Use cloud technologies



If you do not want to bother at all, and money burns your employer's thigh, then you can switch to running tests in cloud services. The infrastructure of such services in general allows you to do miracles of logging, creating reports for runs on different operating systems and in different browsers. Including video of passed tests is available. I do not specifically mention the services - so as not to advertise. Everything is googled.



How to get screen video



With video, it's a little more complicated. You can't just take and shoot a video. Need to dance a little.



There are two main ways to dance:



  • Make screenshots and convert them to video (hereinafter, method 1)
  • Shoot a video immediately (hereinafter, methods 2 and 3)


Method 1. Convert pictures into video by hand (using ffmpeg as an example)



To get a video, you can take screenshots every half a second and then combine them into one video. For example, using the ffmpeg library (https://ffmpeg.org/)



For files with the PNG extension located in the same directory, the command might look like this:



ffmpeg -framerate 1 -pattern_type glob -i '*.png' \ -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4


You can add automation and, for example, make a script that runs a similar command at the end of the tests.



Method 2. Video Recorder - Monte Screen Recorder



Another way to create video is to bypass the step of taking screenshots and use the recorders right away.



The first one I came across was Monte Screen Recorder and below is a small example of using Java wrapper for this recorder (https://github.com/stephenc/monte-screen-recorder):



 GraphicsConfiguration gc = GraphicsEnvironment
            .getLocalGraphicsEnvironment()
            .getDefaultScreenDevice()
            .getDefaultConfiguration(); 
         
    screenRecorder = new ScreenRecorder(gc,
            gc.getBounds(),
            new Format(MediaTypeKey, MediaType.FILE, MimeTypeKey, MIME_AVI),
            new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
                    CompressorNameKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
                    DepthKey, 24, FrameRateKey, Rational.valueOf(15),
                    QualityKey, 1.0f,
                    KeyFrameIntervalKey, 15 * 60),
            new Format(MediaTypeKey, MediaType.VIDEO, EncodingKey, "black", FrameRateKey, Rational.valueOf(30)),
            null,
            new File(targetFolder));
    screenRecorder.start();


The disadvantage of this recorder is that you need the TSC codec installed on your computer to watch videos (https://www.techsmith.com/products.html).



Method 3. Recorder - ffmpeg The



second recorder I came across was the most famous and widely used ffmpeg library. I have already given an example of its use for converting an image into a video. There are several wrappers for the library. I ended up settling on github.com/SergeyPirogov/video-recorder-java .



This library attracted me by the fact that the updates are quite new - it means the project is alive and one can hope that the bugs will be fixed quickly. In addition, the wrapper was written specifically to support our problem - to shoot a video when the tests failed. The easiest way to use is Java annotationsVideo(name = "second_test")



For example:



   @Test
    @Video(name = "second_test")
    public void videoShouldHaveNameSecondTest(){
        Thread.sleep(1000);
        assertTrue(false);
    }


The main thing is to remember that by default the wrapper uses the Monte codec, not ffmpeg. Therefore, do not forget to override the video format in the configuration file (you can see how this is done on the central Git project page).



There will be no output. For myself, I chose VideoRecorder (by Pirogov), but without using annotations, but directly using classes that allow you to start and stop video recording. In the next post I plan to describe this



method.It would be dishonest not to refer to the pages from which the code was honestly stolen for research purposes:





PS: If suddenly, by accident, you have some ideas of what else you can do - please add links or text in the comments. Thanks.



All Articles