Listener that runs at start_test but after all setup has completed

Hi,

I’m trying to create a listener using the v3 API that starts a video recording at the start of each test case, then stops it and the end of each test case. I started with this:

class VcrTestCases(ListenerV3):
    """
    Listener to automatically take a video of each test case
    """

    def __init__(self):
        self.vcr = None

    def start_test(self, data, result):
        self.vcr = VideoRecorder()
        self.vcr.start(name=result.name)

    def end_test(self, data, result):
        time.sleep(2)
        self.vcr.stop(status=result.status)

…which works, but my tests have a lengthy Setup (suite and test case) that takes a few minutes to run and setup a database etc. So the video recording each have a few minutes of nothing happening at the beginning.

I thought then perhaps I just run as follows and try to detect the first keyword:

class VcrTestCases(ListenerV3):
    """
    Listener to automatically take a video of each test case
    """

    def __init__(self):
        self.vcr = None
        self.first_keyword_seen = False
        self.in_test = False

    def start_test(self, data, result):
        self.vcr = VideoRecorder()
        self.in_test = True
        self.first_keyword_seen = False

    def end_test(self, data, result):
        time.sleep(2)
        self.vcr.stop(status=result.status)
        self.in_test = False

    def start_keyword(self, data, result):
        if self.in_test and not self.first_keyword_seen:
            self.first_keyword_seen = True
            self.vcr.start(name=result.name)

…but that had no effect as it starts the video recording at the first keyword of the test setup.

Has anyone come across this before and can suggest a way to run something before the first keyword of a test case that is not suite/test setup?

Cheers,
Kim

A hacky way that I would attempt to do this is by using the listener method start_user_keyword. With this one you could check which keyword is being called and then only proceed to start if it is your Start VCR Test Case Video. The same could then be done for stopping the video.

def start_user_keyword(self, data, implementation, result):
        print(f'data {data}')
        print(f'implementation {implementation}')
        print(f'result {result}')
        if data == 'Start VCR Test Case Video':
              # do your stuff

Hope this might be a useful approach!

1 Like

Thanks @timdegroot1996, I ended up going with your suggestion to use keyword name. To make it a bit less hacky, I use an arument to the listener when it’s registered

class VcrTestCases(ListenerV3):
    """
    Listener to automatically take a video of each test case
    starting the recording when the ``keyword_fullname_trigger`` runs
    and stopping the recording at the end of the test.
    """

    def __init__(self, keyword_fullname_trigger=None):
        self.vcr = None
        self.keyword_fullname_trigger = keyword_fullname_trigger
        self.is_recording = False

    def start_test(self, data, result):
        self.vcr = VideoRecorder()

    def end_test(self, data, result):
        if self.is_recording:
            time.sleep(2)
            self.vcr.stop(status=result.status)
            self.is_recording = False

    def start_keyword(self, data, result):
        if not self.is_recording and result.full_name == self.keyword_fullname_trigger:
            self.vcr.start(name=result.name)
            self.is_recording = True

And where I register the listener I pass the argument like so:

ROBOT_LIBRARY_LISTENER = [VcrTestCases("Client.Start")]
1 Like

Hi,

For info the ScreenCap Library includes the test recording keywords to start and stop. Maybe you can find useful info in the Library.

I use it for debugging by calling keywords in my global test setup/Teardown.
Works well with a control variable to record or not (0, 1) and remove or not (2) depending of the Test status.

*** Keywords ***
Start Test Record
    ScreenCapLibrary.Set Screenshot Directory    ${directory}
    Start Video Recording    alias=currenttest    name=${TEST_NAME}_Record    embed=${False}    fps=${fps}

Stop Test Record
    IF    ${recording} > 0
        Run Keyword And Warn On Failure    Stop Video Recording    alias=currenttest
        IF    ${recording} < 2 and '${TEST_STATUS}' == 'PASS'
            Run Keyword And Warn On Failure    Remove File    ${directory}${/}${TEST_NAME}_Record*.webm
        END
    END

Regards
Charlie