diff --git a/.gitignore b/.gitignore index 6a8ae99..f9db17e 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,5 @@ pyproject.toml requirements.txt requirement/ignore_requirements.txt screenshots +screencasts script/todo/todo_override.json diff --git a/script/selenium/selenium_lib.py b/script/selenium/selenium_lib.py index 476291d..9d71262 100644 --- a/script/selenium/selenium_lib.py +++ b/script/selenium/selenium_lib.py @@ -31,15 +31,21 @@ class SeleniumLib(object): self.config = config self.video_recorder = None if self.config.video_suffix: - self.filename = ( + self.filename_recording = ( f"video_{self.config.video_suffix}_" + time.strftime("%Y_%m_%d-%H_%M_%S") + ".webm" ) else: - self.filename = ( + self.filename_recording = ( "video_" + time.strftime("%Y_%m_%d-%H_%M_%S") + ".webm" ) + dir_path_screencast = os.path.join(".", "screencasts") + self.filename_recording = os.path.join( + dir_path_screencast, self.filename_recording + ) + if not os.path.isdir(dir_path_screencast): + os.mkdir(dir_path_screencast) self.driver = None with open(".odoo-version") as txt: self.odoo_version = txt.read() @@ -109,7 +115,7 @@ class SeleniumLib(object): from script.selenium.selenium_video import VideoRecorder self.video_recorder = VideoRecorder( - self.driver, filename=self.filename + self.driver, filename=self.filename_recording ) # import vlc @@ -637,14 +643,17 @@ class SeleniumLib(object): print("Chatbot cannot be found, stop searching it.") # Website - def odoo_show_robot_message(self, msg="Ho no!"): + def odoo_show_robot_message( + self, msg="Ho no!", hide_message_after_x_seconds=0 + ): # Injecter l'animation SVG dans la page script_text = "" if msg: + msg_to_print = msg.replace("'", "\\'") script_text = f""" // Ajouter le texte const textElement = document.createElement('div'); - textElement.innerText = '{msg}'; + textElement.innerText = '{msg_to_print}'; textElement.style.color = '#FFFFFF'; textElement.style.fontSize = '24px'; textElement.style.marginBottom = '20px'; @@ -657,6 +666,7 @@ class SeleniumLib(object): (function() { // Créer un div pour l'overlay const overlay = document.createElement('div'); + overlay.id = 'uniqueOverlay'; // Ajout de l'ID overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; @@ -670,11 +680,27 @@ class SeleniumLib(object): // Contenu SVG du robot const svgContent = ` - - - - - + + + + + + + + + + + + + + + + + + + + + `; """ @@ -696,6 +722,18 @@ class SeleniumLib(object): # Exécuter le script pour injecter l'animation self.driver.execute_script(script) + if hide_message_after_x_seconds: + time.sleep(hide_message_after_x_seconds) + delete_script = """(function() { + // Sélectionner l'overlay par ses attributs de style uniques + const overlay = document.getElementById('uniqueOverlay'); + + // Vérifier si l'overlay existe et le supprimer + if (overlay) { + overlay.remove(); + } +})();""" + self.driver.execute_script(delete_script) print(f"Script inject robot svg with msg '{msg}'") def odoo_website_menu_click(self, from_text=""): @@ -812,7 +850,9 @@ class SeleniumLib(object): return status_button def odoo_web_form_click_save_action(self): - return self.odoo_web_form_click_by_classname_action("o_form_button_save") + return self.odoo_web_form_click_by_classname_action( + "o_form_button_save" + ) def odoo_web_form_click_web_publish_action(self): return self.odoo_web_form_click_button_action("website_publish_button") @@ -960,10 +1000,13 @@ class SeleniumLib(object): file_name_1 = f"/tmp/erplibre_sync_temp_file{self.config.sync_file_record_write}" file_name_2 = f"/tmp/erplibre_sync_temp_file{self.config.sync_file_record_read}" with open(file_name_1, "w") as file: - file.write(f"Recording {self.filename}\n") + file.write(f"Recording {self.filename_recording}\n") while not os.path.exists(file_name_2): var_wait_time = 0.001 - print(f"File {self.filename} wait {var_wait_time} seconds") + print( + f"File {self.filename_recording} wait" + f" {var_wait_time} seconds" + ) time.sleep(var_wait_time) self.video_recorder.start() @@ -975,10 +1018,19 @@ class SeleniumLib(object): time.sleep(self.config.selenium_video_time_waiting_end) self.video_recorder.stop() print("End of recording video") - print(self.filename) + print(self.filename_recording) + + filename_recording_mp4 = self.filename_recording.replace( + ".webm", ".mp4" + ) + if self.config.selenium_video_auto_convert_mp4: + os.popen( + "ffmpeg -i" + f" {self.filename_recording} {filename_recording_mp4}" + ) if self.config.selenium_video_auto_play_video: - print(f"Play video {self.filename}") + print(f"Play video {self.filename_recording}") # By python-vlc # media_player = vlc.MediaPlayer(filename) # media = vlc.Media(filename) @@ -986,7 +1038,10 @@ class SeleniumLib(object): # media_player.play() # time.sleep(15) # By external process - os.popen(f"vlc {self.filename}") + if self.config.selenium_video_auto_convert_mp4: + os.popen(f"vlc {filename_recording_mp4}") + else: + os.popen(f"vlc {self.filename_recording}") def generer_code_postal_quebec(self): # Zip code from quebec canada @@ -998,7 +1053,9 @@ class SeleniumLib(object): chiffre = str(random.randint(0, 9)) troisieme_lettre = chr(random.randint(65, 90)) - code_postal = f"{premiere_lettre}{chiffre}{deuxieme_lettre} {chiffre}{troisieme_lettre}{chiffre}" + code_postal = ( + f"{premiere_lettre}{chiffre}{deuxieme_lettre} {chiffre}{troisieme_lettre}{chiffre}" + ) return code_postal @@ -1127,3 +1184,9 @@ def fill_parser(parser): action="store_true", help="Autoplay the video when done.", ) + group_record.add_argument( + "--selenium_video_auto_convert_mp4", + action="store_true", + default=True, + help="Will convert .webm to .mp4 when done.", + ) diff --git a/script/selenium/selenium_video.py b/script/selenium/selenium_video.py index c53604a..50d821a 100644 --- a/script/selenium/selenium_video.py +++ b/script/selenium/selenium_video.py @@ -26,7 +26,7 @@ class VideoRecorder(object): self, driver, filename="video.webm", - framerate="33/1", + framerate="5/1", width=None, height=None, ):