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?
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
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:
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