[IMP] tests: add test for screencast

Screencast are not always enable and a recent change broke the ffmpeg
call. This call was already broken in some ffmpeg versions.

This test will help to ensure this feature continues to work, and will
also test it in different ffmpeg versions during distro builds.

closes odoo/odoo#156738

X-original-commit: a3d6ef64e218683f7455f60d20860b62780be3b9
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
This commit is contained in:
Xavier-Do
2024-03-07 08:25:55 +00:00
parent 46fc951e0b
commit 63214e55e8
2 changed files with 39 additions and 8 deletions
+21 -3
View File
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import HttpCase, tagged
from odoo.tools import mute_logger, logging
from odoo.tests.common import HttpCase, tagged, ChromeBrowser
from odoo.tools import config, logging
from unittest.mock import patch
@tagged('-at_install', 'post_install')
@@ -47,5 +47,23 @@ class TestHttpCase(HttpCase):
if text == 'test successful':
continue
self.assertEqual(text, "Object(custom=Object, value=1, description='dummy')")
console_log_count +=1
console_log_count += 1
self.assertEqual(console_log_count, 1)
@tagged('-at_install', 'post_install')
class TestChromeBrowser(HttpCase):
def setUp(self):
super().setUp()
screencasts_dir = config['screencasts'] or config['screenshots']
with patch.dict('odoo.tools.config.options', {'screencasts': screencasts_dir, 'screenshots': config['screenshots']}):
self.browser = ChromeBrowser(self)
self.addCleanup(self.browser.stop)
def test_screencasts(self):
self.browser.start_screencast()
self.browser.navigate_to('about:blank')
self.browser._wait_ready()
code = "setTimeout(() => console.log('test successful'), 2000); setInterval(() => document.body.innerText = (new Date()).getTime(), 100);"
self.browser._wait_code_ok(code, 10)
self.browser._save_screencast()
+18 -5
View File
@@ -957,9 +957,11 @@ class ChromeBrowser:
def stop(self):
if hasattr(self, 'ws'):
self._websocket_send('Page.stopScreencast')
if self.screencasts_dir and os.path.isdir(self.screencasts_frames_dir):
if self.screencasts_dir:
screencasts_frames_dir = self.screencasts_frames_dir
self.screencasts_dir = None
shutil.rmtree(self.screencasts_frames_dir)
if os.path.isdir(screencasts_frames_dir):
shutil.rmtree(screencasts_frames_dir, ignore_errors=True)
self._websocket_request('Page.stopLoading')
self._websocket_request('Runtime.evaluate', params={'expression': """
@@ -1345,6 +1347,8 @@ which leads to stray network requests and inconsistencies."""
wait()
def _handle_screencast_frame(self, sessionId, data, metadata):
if not self.screencasts_frames_dir:
return
self._websocket_send('Page.screencastFrameAck', params={'sessionId': sessionId})
if not self.screencasts_dir:
return
@@ -1391,6 +1395,8 @@ which leads to stray network requests and inconsistencies."""
self._logger.debug('No screencast frames to encode')
return None
self.stop_screencast()
for f in self.screencast_frames:
with open(f['file_path'], 'rb') as b64_file:
frame = base64.decodebytes(b64_file.read())
@@ -1418,7 +1424,11 @@ which leads to stray network requests and inconsistencies."""
duration = end_time - self.screencast_frames[i]['timestamp']
concat_file.write("file '%s'\nduration %s\n" % (frame_file_path, duration))
concat_file.write("file '%s'" % frame_file_path) # needed by the concat plugin
r = subprocess.run([ffmpeg_path, '-intra', '-f', 'concat','-safe', '0', '-i', concat_script_path, '-pix_fmt', 'yuv420p', outfile])
try:
subprocess.run([ffmpeg_path, '-f', 'concat', '-safe', '0', '-i', concat_script_path, '-pix_fmt', 'yuv420p', '-g', '0', outfile], check=True)
except subprocess.CalledProcessError:
self._logger.error('Failed to encode screencast.')
return
self._logger.log(25, 'Screencast in: %s', outfile)
else:
outfile = outfile.strip('.mp4')
@@ -1429,6 +1439,9 @@ which leads to stray network requests and inconsistencies."""
assert self.screencasts_dir
self._websocket_send('Page.startScreencast')
def stop_screencast(self):
self._websocket_send('Page.stopScreencast')
def set_cookie(self, name, value, path, domain):
params = {'name': name, 'value': value, 'path': path, 'domain': domain}
self._websocket_request('Network.setCookie', params=params)
@@ -1440,7 +1453,8 @@ which leads to stray network requests and inconsistencies."""
self._websocket_request('Network.deleteCookies', params=params)
return
def _wait_ready(self, ready_code, timeout=60):
def _wait_ready(self, ready_code=None, timeout=60):
ready_code = ready_code or "document.readyState === 'complete'"
self._logger.info('Evaluate ready code "%s"', ready_code)
start_time = time.time()
result = None
@@ -1809,7 +1823,6 @@ class HttpCase(TransactionCase):
# Needed because tests like test01.js (qunit tests) are passing a ready
# code = ""
ready = ready or "document.readyState === 'complete'"
self.assertTrue(browser._wait_ready(ready), 'The ready "%s" code was always falsy' % ready)
error = False