From 63214e55e82ce0c34479a275c3f2695b5a45c7c0 Mon Sep 17 00:00:00 2001 From: Xavier-Do Date: Tue, 30 Jan 2024 15:21:18 +0000 Subject: [PATCH] [IMP] tests: add test for screencast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) Signed-off-by: Xavier Dollé (xdo) --- odoo/addons/base/tests/test_http_case.py | 24 +++++++++++++++++++++--- odoo/tests/common.py | 23 ++++++++++++++++++----- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/odoo/addons/base/tests/test_http_case.py b/odoo/addons/base/tests/test_http_case.py index b0323091a24..85b09f3a8a3 100644 --- a/odoo/addons/base/tests/test_http_case.py +++ b/odoo/addons/base/tests/test_http_case.py @@ -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() diff --git a/odoo/tests/common.py b/odoo/tests/common.py index efda46aa811..f569cbca658 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -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