From 8b57cdc546cfe391179d52bb39bad62e7656fd06 Mon Sep 17 00:00:00 2001 From: Jeff Wilder Date: Tue, 5 May 2026 01:59:27 -0700 Subject: [PATCH 1/2] Web Youtube scenarios - optionally take a screen for verification. Scenario Maker - updated InputInject calls to work with current InputInject. hobl - set default platform to [PLATFORM] to determine automatically. hobl - prevent prior dut communication if scenario is comm_check. comm_check - Use platform-agnostic commands so that platform doesn't have to be determined prior. Updated MacOS setup instructions. standby - connected standby scenario. recharge - added parameter to stay on charger for specified time. auto_recharge - added parameter to delay specified time after turning off charger to let system quiesce. --- ScenarioMaker/tab.py | 10 +++--- core/hobl.py | 4 +-- docs/support/docs/HOBL_Setup.md | 27 ++++++++++----- scenarios/common/comm_check.py | 17 +++++----- .../web_site_youtube_nasa/code_1KN4CL2.py | 16 +++++++++ .../web_site_youtube_nasa.json | 11 +++++++ .../site/web_site_youtube_tos/code_1KN4CL1.py | 16 +++++++++ .../web_site_youtube_tos.json | 17 ++++++++-- scenarios/windows/cs_floor/cs_floor.py | 10 +++--- .../windows/cs_floor/cs_floor_wrapper.cmd | 33 ++++++++++--------- scenarios/windows/recharge.py | 10 ++++++ scenarios/windows/standby.py | 13 ++++++++ testplans/hobl.ps1 | 4 +-- tools/auto_recharge.py | 9 +++++ 14 files changed, 149 insertions(+), 48 deletions(-) create mode 100644 scenarios/windows/_library/web/site/web_site_youtube_nasa/code_1KN4CL2.py create mode 100644 scenarios/windows/_library/web/site/web_site_youtube_tos/code_1KN4CL1.py create mode 100644 scenarios/windows/standby.py diff --git a/ScenarioMaker/tab.py b/ScenarioMaker/tab.py index 500c2068..f57d7c43 100644 --- a/ScenarioMaker/tab.py +++ b/ScenarioMaker/tab.py @@ -167,7 +167,7 @@ def update_mouse_wheel(self, event): y_frac = max(0, dut_y / self.main_win.dut_screen_height) action = self.actionModel.appendAction(self.working_dir, type=self.action_type, x="{:.3f}".format(x_frac), y="{:.3f}".format(y_frac), delay=str(self.settings.get("default_delay")), direction=dir) if self.main_win.connected: - result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Scroll", dut_x, dut_y, 720, dir, self.main_win.current_display) + result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Scroll", dut_x, dut_y, 720, dir, self.main_win.current_display, "0", "0", 0, 0, 0, 0, 0, 0) # else squash events elif self.mode_select or self.mode_record: @@ -202,7 +202,7 @@ def update_mouse_wheel(self, event): dir = "up" dut_x, dut_y = self.image_to_dut_coords(self.selection_x, self.selection_y) if self.main_win.connected: - result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Scroll", dut_x, dut_y, 120, dir, self.main_win.current_display) + result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Scroll", dut_x, dut_y, 120, dir, self.main_win.current_display, "0", "0", 0, 0, 0, 0, 0, 0) @pyqtSlot(QtGui.QMouseEvent) def update_mouse_move(self, event): @@ -381,7 +381,7 @@ def keyPressEvent(self, event): self.action_typing_str += key_text if self.main_win.connected: print(f"Sending: {key_text}") - result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Type", key_text, 0) + result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Type", key_text, 0, "0", 0, 0, 0, 0, 0, 0) elif only_shift: # if Shift is pressed, convert to uppercase if key_text.isalpha(): @@ -391,7 +391,7 @@ def keyPressEvent(self, event): self.labelImage.clearSelect() self.action_typing_str = self.convert_capitals(self.action_typing_str) + key_text if self.main_win.connected: - result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Type", key_text, 0) + result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Type", key_text, 0, "0", 0, 0, 0, 0, 0, 0) else: self.modifier_string += key_text self.action_typing_str += key_text @@ -431,7 +431,7 @@ def keyReleaseEvent(self, event): # self.action_typing_str = self.convert_capitals(self.action_typing_str) print(f"Sending mstring: {self.modifier_string}") if self.main_win.connected: - result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Type", self.modifier_string, 150) + result = rpc.plugin_call(self.dut_ip, 8000, "InputInject", "Type", self.modifier_string, 150, "0", 0, 0, 0, 0, 0, 0, 0) self.modifier_string = "" if self.mode_typing or self.mode_record: self.create_typing_action() diff --git a/core/hobl.py b/core/hobl.py index 262bc935..f7f56001 100644 --- a/core/hobl.py +++ b/core/hobl.py @@ -65,7 +65,7 @@ params.setDefault('global', 'run_type', '', desc="A results sub-folde to indicate the type of run it is, such as 'Power', 'ETL', 'Misc', etc.") params.setDefault('global', 'iterations', '1', desc="How many time to repeat the scenario.") params.setDefault('global', 'training_mode', '0', desc="Specify if this is a training run (1) or not (0).", valOptions=["0", "1"]) -params.setDefault('global', 'platform', 'Windows', desc="Operating system platform.", valOptions=["Windows", "Android", "W365", "MacOS"]) +params.setDefault('global', 'platform', '[PLATFORM]', desc="Operating system platform.", valOptions=["[PLATFORM]", "Windows", "Android", "W365", "MacOS"]) params.setDefault('global', 'msa_account', '', desc="The test account that Windows and apps will be logged in with.") params.setDefault('global', 'dut_password', '', desc="The password for the test account (msa_account).") params.setDefault('global', 'dut_ip', '127.0.0.1', desc="IP address of the Device Under Test (name can be used if DNS is supported).") @@ -201,7 +201,7 @@ # Check if we're runnign a scenario that shouldn't contact the DUT before # loading params, which can make calls to the DUT -for scenario in ['charge_off', 'charge_on', 'hard_reboot', 'sleep_wake', 'manual_offline', 'study_report', 'run_report', 'dut_setup']: +for scenario in ['comm_check', 'charge_off', 'charge_on', 'hard_reboot', 'sleep_wake', 'manual_offline', 'study_report', 'run_report', 'dut_setup']: if scenario in sys.argv: print("Forcing dut_alive to 0") Params.setCalculated("dut_alive", '0') diff --git a/docs/support/docs/HOBL_Setup.md b/docs/support/docs/HOBL_Setup.md index 8a581937..2bb7988b 100644 --- a/docs/support/docs/HOBL_Setup.md +++ b/docs/support/docs/HOBL_Setup.md @@ -79,19 +79,28 @@ Set up a Device Profile for each DUT in the HOBLweb UI, giving it a unique name 1. If you see an error when it tries to set the developer mode, this can safely be ignored. 4. Test network connection to the DUT: 1. Host and DUT need to be on the same subnet (first 2 octets of the IP address). - 1. Run Cmd or Powershell on the Host. - 1. Make sure sure DUT responds to pings: `ping ` + 1. Run Cmd or Powershell on the Host, and make sure sure DUT responds to pings: `ping ` 1. Make sure DUT can ping host as well. 1. Run the "comm_check" scenario to make sure that all communications needs are met. ## DUT Setup For macOS -1. Manually make sure the device is onnected to the appropriate Wi-Fi netowrk, on the same subnet as the Host. -1. After running host_setup.exe, dut_setup.sh should be found in the /downloads/Setup folder. Copy dut_setup.sh from here to a USB stick. -1. Plug the USB stick into the DUT and execute dut_setup.sh. -1. There will be numerous prompts for password and to enable various security items. It's critical to enable all. -1. Test network connection to the DUT: +1. Manually set up the Mac with an account and connect the device to the appropriate Wi-Fi netowrk, on the same subnet as the Host. +2. If Global Secure Access app exists, disable it. It prevents peer-to-peer communication. +3. Change settings to do auto-login: + a. System Settings -> Users & Groups -> Automatically log in as: specify account and password +4. Copy hobl\downloads\setup\dut_setup_.sh to Mac using a FAT32 formatted USB stick, and execute from terminal window. You will be prompted for password and access permissions multiple times. Be sure to enable everything. If you don't see dut_setup_\\.sh in the hobl\downloads\setup folder, then do [Host Setup](#host-setup). +5. Either disable firewall, or disable "Stealth Mode" in Firewall Options (to allow pings to go through) +6. Use light meter to adjust screen brightness to 150 nits, on DC with white background. Then run /users/Shared/hobl_bin/brightness -l to report setting level. Multiply that fraction by 100 to turn to percentage, to set display:brightness in profile. +7. Leave audio level at out-of-box setting. +8. The first time you run some tests or tools there may be various permissions popups. Manually allow them all. Then subsequent runs should work without interference. +10. Set keyboard shortcut Shift-Cmd-H to Safari "Clear History…" + a. Settings -> Keyboard -> Keyboard Shortcuts -> App Shortcuts + b. Application: "Safari" + c. Menu title: "Clear History…" (the three dots are critical) + d. Keyboard shortcut: "Shift-Cmd-H" +11. Set Safari history clear to "All History" +12. Test network connection to the DUT: 1. Host and DUT need to be on the same subnet (first 2 octets of the IP address). - 1. Run Cmd or Powershell on the Host. - 1. Make sure sure DUT responds to pings: `ping ` + 1. Run Cmd or Powershell on the Host, and make sure sure DUT responds to pings: `ping ` 1. Make sure DUT can ping host as well. 1. Run the "comm_check" scenario to make sure that all communications needs are met. diff --git a/scenarios/common/comm_check.py b/scenarios/common/comm_check.py index d8ea1f92..05391df4 100644 --- a/scenarios/common/comm_check.py +++ b/scenarios/common/comm_check.py @@ -72,15 +72,16 @@ def runTest(self): # Async SimpleRemote if (self.async_comm == "1"): try: - if self.platform.lower() == "windows": - output = self._call(["cmd.exe", "/c echo ok"], timeout=5) - elif self.platform.lower() == "macos": - output = self._call(["zsh", '-c "echo ok"'], timeout=5) - else: - logging.error(f"Unsupported platform {self.platform}") - self.fail(f"Unsupported platform {self.platform}") + output = self._call(["curl", "-V"], timeout=5) + # if self.platform.lower() == "windows": + # output = self._call(["cmd.exe", "/c echo ok"], timeout=5) + # elif self.platform.lower() == "macos": + # output = self._call(["zsh", '-c "echo ok"'], timeout=5) + # else: + # logging.error(f"Unsupported platform {self.platform}") + # self.fail(f"Unsupported platform {self.platform}") logging.debug(output) - if "ok" in output: + if "Release-Date" in output: logging.info("SimpleRemote Async:\tOK") else: logging.info("SimpleRemote Async:\tFAIL") diff --git a/scenarios/windows/_library/web/site/web_site_youtube_nasa/code_1KN4CL2.py b/scenarios/windows/_library/web/site/web_site_youtube_nasa/code_1KN4CL2.py new file mode 100644 index 00000000..36d7f669 --- /dev/null +++ b/scenarios/windows/_library/web/site/web_site_youtube_nasa/code_1KN4CL2.py @@ -0,0 +1,16 @@ +# Copyright (c) Microsoft. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import logging +from core.parameters import Params + +def run(scenario): + logging.debug('Executing code block: code_1KN4CL2.py') + enable = Params.get("web", "youtube_screenshot") + if enable == "1": + index = Params.get("youtube_nasa", "screenshot_index") + if index == None or "": + index = 0 + index = int(index) + scenario._screenshot(f"youtube_nasa_{index:03}.png") + Params.setParam("youtube_nasa", "screenshot_index", str(index+1)) \ No newline at end of file diff --git a/scenarios/windows/_library/web/site/web_site_youtube_nasa/web_site_youtube_nasa.json b/scenarios/windows/_library/web/site/web_site_youtube_nasa/web_site_youtube_nasa.json index a731be8b..6ffdf1dc 100644 --- a/scenarios/windows/_library/web/site/web_site_youtube_nasa/web_site_youtube_nasa.json +++ b/scenarios/windows/_library/web/site/web_site_youtube_nasa/web_site_youtube_nasa.json @@ -189,6 +189,17 @@ "id": "UCL4U1", "type": "Delay" }, + { + "children": [], + "delay": "0.0", + "description": "Capture screenshot", + "enabled": true, + "file_name": [ + "code_1KN4CL2.py" + ], + "id": "1KN4CL2", + "type": "Code" + }, { "children": [], "delay": "0", diff --git a/scenarios/windows/_library/web/site/web_site_youtube_tos/code_1KN4CL1.py b/scenarios/windows/_library/web/site/web_site_youtube_tos/code_1KN4CL1.py new file mode 100644 index 00000000..d66caebe --- /dev/null +++ b/scenarios/windows/_library/web/site/web_site_youtube_tos/code_1KN4CL1.py @@ -0,0 +1,16 @@ +# Copyright (c) Microsoft. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import logging +from core.parameters import Params + +def run(scenario): + logging.debug('Executing code block: code_1KN4CL1.py') + enable = Params.get("web", "youtube_screenshot") + if enable == "1": + index = Params.get("youtube_tos", "screenshot_index") + if index == None or "": + index = 0 + index = int(index) + scenario._screenshot(f"youtube_tos_{index:03}.png") + Params.setParam("youtube_tos", "screenshot_index", str(index+1)) \ No newline at end of file diff --git a/scenarios/windows/_library/web/site/web_site_youtube_tos/web_site_youtube_tos.json b/scenarios/windows/_library/web/site/web_site_youtube_tos/web_site_youtube_tos.json index 4ed4c8c0..5d5c43df 100644 --- a/scenarios/windows/_library/web/site/web_site_youtube_tos/web_site_youtube_tos.json +++ b/scenarios/windows/_library/web/site/web_site_youtube_tos/web_site_youtube_tos.json @@ -70,7 +70,7 @@ "description": "", "enabled": true, "id": "UE5XLM", - "include_path": "..\\..\\..\\misc\\recording_phase_begin", + "include_path": "scenarios\\windows\\_library\\misc\\recording_phase_begin", "type": "Include" }, { @@ -90,7 +90,7 @@ "description": "", "enabled": true, "id": "UC5PAR", - "include_path": "..\\..\\web_enter_address", + "include_path": "scenarios\\windows\\_library\\web\\web_enter_address", "params": [ { "name": "[web_site_address]", @@ -291,6 +291,17 @@ "id": "UCL4U1", "type": "Delay" }, + { + "children": [], + "delay": "0.0", + "description": "Capture screenshot", + "enabled": true, + "file_name": [ + "code_1KN4CL1.py" + ], + "id": "1KN4CL1", + "type": "Code" + }, { "children": [ { @@ -401,7 +412,7 @@ "description": "", "enabled": true, "id": "UE5XV7", - "include_path": "..\\..\\..\\misc\\recording_phase_end", + "include_path": "scenarios\\windows\\_library\\misc\\recording_phase_end", "params": [ { "name": "[phase_category]", diff --git a/scenarios/windows/cs_floor/cs_floor.py b/scenarios/windows/cs_floor/cs_floor.py index a4cbf83f..c1628dad 100644 --- a/scenarios/windows/cs_floor/cs_floor.py +++ b/scenarios/windows/cs_floor/cs_floor.py @@ -28,6 +28,7 @@ class CS(core.app_scenario.Scenario): Params.setDefault('cs_floor', 'button_wake_callback', '') Params.setDefault('cs_floor', 'local_button', '1') # 0 = host, 1 = DUT Params.setDefault('cs_floor', 'sleep_mode', '') # Blank = connected standby, "S3" for S3. + Params.setDefault('cs_floor', 'connection', 'Disconnected', desc="Connected or Disconnected from the network during standby", valOptions=["Disconnected", "Connected"]) prep_scenarios = ["button_install"] @@ -42,6 +43,7 @@ def setUp(self): self.local_button = Params.get('cs_floor', 'local_button') self.local_execution = Params.get('global', 'local_execution') self.sleep_mode = Params.get('cs_floor', 'sleep_mode') + self.connection = Params.get('cs_floor', 'connection') self.wifi_off_duration = str((int(self.cs_duration)) + (int(self.button_to_record_delay)) + 15) @@ -64,8 +66,8 @@ def setUp(self): if self.button_sleep != '': try: - logging.info('DUT command: cmd.exe /C ' + self.dut_exec_path + '\\cs_floor_resources\\cs_floor_wrapper.cmd ' + str(15)) - self._call(["cmd.exe", "/C " + os.path.join(self.dut_exec_path, "cs_floor_resources", "cs_floor_wrapper.cmd") + ' ' + str(15)], blocking = False) + logging.info('DUT command: cmd.exe /C ' + self.dut_exec_path + '\\cs_floor_resources\\cs_floor_wrapper.cmd ' + str(15) + " " + self.connection) + self._call(["cmd.exe", "/C " + os.path.join(self.dut_exec_path, "cs_floor_resources", "cs_floor_wrapper.cmd") + ' ' + str(15) + " " + self.connection], blocking = False) except: pass time.sleep(5) @@ -84,8 +86,8 @@ def setUp(self): else: # Connected Standby logging.info("Calling Button.exe on DUT") try: - logging.info("DUT command: cmd.exe /C " + self.dut_exec_path + "\\cs_floor_resources\\cs_floor_wrapper.cmd " + self.wifi_off_duration + " " + self.dut_exec_path) - self._call(["cmd.exe", "/C " + os.path.join(self.dut_exec_path, "cs_floor_resources", "cs_floor_wrapper.cmd") + ' ' + self.wifi_off_duration + " " + self.dut_exec_path], blocking = False) + logging.info("DUT command: cmd.exe /C " + self.dut_exec_path + "\\cs_floor_resources\\cs_floor_wrapper.cmd " + self.wifi_off_duration + " " + self.connection + " " + self.dut_exec_path) + self._call(["cmd.exe", "/C " + os.path.join(self.dut_exec_path, "cs_floor_resources", "cs_floor_wrapper.cmd") + ' ' + self.wifi_off_duration + " " + self.connection + " " + self.dut_exec_path], blocking = False) time.sleep(2) except: logging.error("button.exe not found on DUT") diff --git a/scenarios/windows/cs_floor/cs_floor_wrapper.cmd b/scenarios/windows/cs_floor/cs_floor_wrapper.cmd index 5a550cc2..008e57aa 100644 --- a/scenarios/windows/cs_floor/cs_floor_wrapper.cmd +++ b/scenarios/windows/cs_floor/cs_floor_wrapper.cmd @@ -1,29 +1,32 @@ @echo off -:: Copyright (c) Microsoft. All rights reserved. -:: Licensed under the MIT license. See LICENSE file in the project root for full license information. - setlocal enabledelayedexpansion cls set wifi_off_duration=%1 echo Wifi off time (sec): %wifi_off_duration% rem if dut_exec_path is not empty, call button.exe on dut and multiply button_delay by 1000 -if [%2] NEQ [] set dut_exec_path=%2 -if [%2] NEQ [] echo DUT Path: %dut_exec_path% -if [%2] NEQ [] set /a button_delay=%wifi_off_duration% * 1000 -if [%2] NEQ [] echo Button Delay: %button_delay% +if [%3] NEQ [] set dut_exec_path=%3 +if [%3] NEQ [] echo DUT Path: %dut_exec_path% +if [%3] NEQ [] set /a button_delay=%wifi_off_duration% * 1000 +if [%3] NEQ [] echo Button Delay: %button_delay% for /f "delims=: tokens=2" %%n in ('netsh wlan show interface name="Wi-Fi" ^| findstr ^/R "\= int(self.resume_threshold): logging.info("Charging complete") + delay = 0 + try: + delay = int(self.post_charge_delay) + except: + logging.error(f"Invalid post_charge_delay setting: {self.post_charge_delay}. Make sure it's an integer.") + else: + logging.info(f"Delaying for {delay} seconds.") + time.sleep(delay) if (self.leave_on_ac == '0'): self.chargeOff() # TODO: handle errors diff --git a/scenarios/windows/standby.py b/scenarios/windows/standby.py new file mode 100644 index 00000000..97e20e41 --- /dev/null +++ b/scenarios/windows/standby.py @@ -0,0 +1,13 @@ +# Copyright (c) Microsoft. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. + +from parameters import Params +Params.setParam("cs_floor", "connection", "Connected") + +import scenarios.windows.cs_floor + +class Standby(scenarios.windows.cs_floor.CS): + ''' + Puts the device into standby mode, still conneccted to the network. + ''' + pass \ No newline at end of file diff --git a/testplans/hobl.ps1 b/testplans/hobl.ps1 index 50b707d2..26ee2bcf 100644 --- a/testplans/hobl.ps1 +++ b/testplans/hobl.ps1 @@ -17,8 +17,8 @@ if ($ARGS[0] -eq $null) {return("Params .ini not supplied, please supply a param .\hobl.cmd -p $ARGS[0] -s teams2_1on1_audio global:iterations=3 global:attempts=2 global:run_type=Power global:tools="+power_light" .\hobl.cmd -p $ARGS[0] -s teams2_1on1_video global:iterations=3 global:attempts=2 global:run_type=Power global:tools="+power_light" .\hobl.cmd -p $ARGS[0] -s teams2_idle global:iterations=3 global:attempts=2 global:run_type=Power global:tools="+power_light" -# .\hobl.cmd -p $ARGS[0] -s idle_desktop global:iterations=3 global:run_type=Power global:tools="+power_light" -# .\hobl.cmd -p $ARGS[0] -s cs_floor global:iterations=3 global:run_type=Power global:tools="+powercfg power_light" +.\hobl.cmd -p $ARGS[0] -s idle_desktop global:iterations=1 global:run_type=Power global:tools="+power_light" +.\hobl.cmd -p $ARGS[0] -s cs_floor global:iterations=1 global:run_type=Power global:tools="+powercfg power_light" .\hobl.cmd -p $ARGS[0] -s charge_on global:run_type=Misc .\hobl.cmd -p $ARGS[0] -s study_report global:run_type=Misc .\hobl.cmd -p $ARGS[0] -s version_report global:run_type=Prep global:post_run_delay=0 diff --git a/tools/auto_recharge.py b/tools/auto_recharge.py index eb18a19f..203ee747 100644 --- a/tools/auto_recharge.py +++ b/tools/auto_recharge.py @@ -20,10 +20,12 @@ class Tool(Scenario): Params.setDefault(module, 'resume_threshold', '95') # Percent battery level (95%) Params.setDefault('charge_on', 'charge_on_call', '') Params.setDefault('charge_off', 'charge_off_call', '') + Params.setDefault(module, 'post_charge_delay', '1800', desc="How many seconds to wait after reaching the resume_threshold before disconnecting charger.") # Adding time here can help sensure the device is maximally charged. # Get parameters charge_threshold = Params.get(module, 'charge_threshold') resume_threshold = Params.get(module, 'resume_threshold') + post_charge_delay = Params.get(module, 'post_charge_delay') charge_on_call = Params.get('global', 'charge_on_call') charge_off_call = Params.get('global', 'charge_off_call') @@ -77,6 +79,13 @@ def initCallback(self, scenario): if count == MAX_COUNT: logging.info(f"Disengaging charger since seeing same battery level for {MAX_COUNT} times.") self.chargeOff() + try: + delay = int(self.post_charge_delay) + except: + logging.error(f"Invalid post_charge_delay setting: {self.post_charge_delay}. Make sure it's an integer.") + else: + logging.info(f"Delaying for {delay} seconds to let device quiesce.") + time.sleep(delay) break time.sleep(300) # sleep 5 minutes old_batt_level = batt_level From cacb1d0a4828fb4425ec7c45e6432d5f29059d69 Mon Sep 17 00:00:00 2001 From: Jeff Wilder Date: Tue, 5 May 2026 02:11:26 -0700 Subject: [PATCH 2/2] screen_record - added parameter for MacOS capture device. --- tools/screen_record.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tools/screen_record.py b/tools/screen_record.py index 45527c1f..fa1cfec5 100644 --- a/tools/screen_record.py +++ b/tools/screen_record.py @@ -12,8 +12,9 @@ class Tool(Scenario): Records a screen cast from the DUT for debug purposes. Has considerable power impact. ''' module = __module__.split('.')[-1] + Params.setDefault(module, 'device_index', '2', desc="MacOS-only. 1 for older or non-Pro macbooks", valOptions=["1", "2"]) # MacOS-only. 1 for older or non-Pro macbooks - local_execution = Params.get('global', 'local_execution') + device_index = Params.get(module, 'device_index') already_started = False @@ -48,14 +49,11 @@ def testBeginCallback(self): cmd = os.path.join(self.dut_exec_path, "ffmpeg.exe") args = "-f gdigrab -framerate 6 -i desktop -loglevel quiet -c:v libx264 -tune stillimage -crf 40 -pix_fmt yuv420p " + output_file stop_key = "q" - if self.local_execution == "0": - self._call([os.path.join(self.dut_exec_path, "command_wrapper.ps1"), cmd + " \"" + args + "\" " + self.stop_file + " " + stop_key], blocking=False) - else: - self._call(["powershell.exe", os.path.join(self.dut_exec_path, "command_wrapper.ps1"), " \"" + cmd + " \'" + args + "\' " + self.stop_file + " " + stop_key + "\"" ], blocking=False) + self._call(["powershell.exe", os.path.join(self.dut_exec_path, "command_wrapper.ps1"), " \"" + cmd + " \'" + args + "\' " + self.stop_file + " " + stop_key + "\"" ], blocking=False) elif self.platform.lower() == "macos": output_file = self.scenario.dut_data_path + "/" + self.scenario.testname + "_recording.mp4" cmd = "/opt/homebrew/bin/ffmpeg" - args = "-capture_cursor 1 -capture_mouse_clicks 1 -f avfoundation -framerate 6 -i 1 -loglevel quiet -c:v libx264 -tune stillimage -crf 40 -pix_fmt yuv420p " + output_file + args = f"-capture_cursor 1 -capture_mouse_clicks 1 -f avfoundation -framerate 6 -i {self.device_index} -loglevel quiet -c:v libx264 -tune stillimage -crf 40 -pix_fmt yuv420p " + output_file self._call(["/bin/bash", self.dut_exec_path + "/command_wrapper.sh " + cmd + " \"" + args + "\" " + self.stop_file + " " + "kill"], blocking=False) logging.info("Screen Recording started.")