2

I'm using Selenium 3 webdriver and Python 3 in Windows 7.

I want to record a video of what's happening in my selenium tests.

To do so I'm using FFmpeg and screen-capture-recorder but I can change programs.

Here's my code:

import unittest
from selenium import webdriver
from subprocess import Popen
#from subprocess import call


cmd = 'ffmpeg -y -rtbufsize 2000M -f dshow -i video="screen-capture-recorder" -r 10 -t 20 screen-capture.mp4'

class SearchProductTest(unittest.TestCase):
    def setUp(self):

        # start the recording of movie
        self.videoRecording = Popen(cmd)

        # create a new Firefox session
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.driver.maximize_window()

        # navigate to the application home page
        self.driver.get("http://demo-store.seleniumacademy.com/")

    def test_search_by_category(self):
        # get the search textbox
        search_field = self.driver.find_element_by_name("q")
        search_field.clear()

        # enter search keyword and submit
        search_field.send_keys("phones")
        search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver.find_elements_by_xpath(
            "//h2[@class='product-name']/a")

        # check count of products shown in results
        self.assertEqual(3, len(products))
        #self.videoRecording.terminate()

    def test_something_else(self):
        pass

    def tearDown(self):
        # close the browser window
        self.driver.quit()

        # Stop the recording
        self.videoRecording.terminate()

    #def terminate(process):
        #if process.poll() is None:
        #    call('taskkill /F /T /PID ' + str(process.pid))

if __name__ == '__main__':
    unittest.main(verbosity=2)

The problems are:

1) the cmd gives a max time per the movie (20" in the example). If the test last more the movie is created and it works (but is incomplete, only 20").

2) if the test last less the file is created but it doesn't work (the reader can't read it and it's just some bytes). This is the main error! I'm not sure about where to start the movie and where (and how) to stop it.

3) If I have more than one test I would like to have only one movie for all of them (so I want to record all the tests in the same movie).

4) if possible I would prefer to record the webdriver window (the one where my tests are running) and not my screen so meanwhile the tests go I can do something else (they are slow).

Thanks you for the help.

fabio
  • 1,210
  • 2
  • 26
  • 55

2 Answers2

1

WebDriver has 3 methods which could be useful for you, get_screenshot_as_png, get_screenshot_as_base64 and get_screenshot_as_file. With that you can took screenshots in background thread and use OpenCV and PIL to generate a video file from the results.

If you don't want to introduce new dependencies you also dump screenshots to files and in the end use ffmpeg to generate a video as well.

szatkus
  • 1,292
  • 6
  • 14
  • To make a movie from screenshot do you think is efficient? – fabio Feb 02 '19 at 09:45
  • Not much less efficient than screen-capture-recorder as long as you process them in memory. In practice probably both methods will have negligible effect on performance. Modern computers are fast. – szatkus Feb 02 '19 at 11:28
  • this won't work well because screenshots are generated from geckodriver and include a blocking http request. so performance *will be* an issue. – Corey Goldberg Feb 02 '19 at 13:37
-1

I did not try this, but it should work anyway. Your code terminates the ffmpeg process. The software cannot finish the video file. The following code should end the process gracefully:

self.videoRecording.send_signal(subprocess.CTRL_C_EVENT)
self.videoRecording.wait()

You will need additional parameters for your popen statement. Please refer to https://docs.python.org/3.7/library/subprocess.html.

import subprocess
...
Popen(cmd, creationflags = subprocess.CREATE_NEW_PROCESS_GROUP)

You can also repair corrupt video files with ffmpeg:

ffmpeg -err_detect ignore_err -i screen-capture.mp4 -c copy video_fixed-screen-capture.mp4
Jens Dibbern
  • 1,434
  • 2
  • 13
  • 20
  • It doesn't work. The software doesn't stop. Also what else I need in my popen statement? To do what? To make it works? Thank you – fabio Feb 05 '19 at 21:48