Skip to content
Merged

Dev #54

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions ScenarioMaker/tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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():
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions core/hobl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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).")
Expand Down Expand Up @@ -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')
Expand Down
27 changes: 18 additions & 9 deletions docs/support/docs/HOBL_Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <dut_ip>`
1. Run Cmd or Powershell on the Host, and make sure sure DUT responds to pings: `ping <dut_ip>`
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_<ver>.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_\<ver>\.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 <dut_ip>`
1. Run Cmd or Powershell on the Host, and make sure sure DUT responds to pings: `ping <dut_ip>`
1. Make sure DUT can ping host as well.
1. Run the "comm_check" scenario to make sure that all communications needs are met.
17 changes: 9 additions & 8 deletions scenarios/common/comm_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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))
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
@@ -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))
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
{
Expand All @@ -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]",
Expand Down Expand Up @@ -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": [
{
Expand Down Expand Up @@ -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]",
Expand Down
10 changes: 6 additions & 4 deletions scenarios/windows/cs_floor/cs_floor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand All @@ -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)

Expand All @@ -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)
Expand All @@ -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")
Expand Down
33 changes: 18 additions & 15 deletions scenarios/windows/cs_floor/cs_floor_wrapper.cmd
Original file line number Diff line number Diff line change
@@ -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 "\<SSID"') do set "this_ssid=%%n"
set "this_ssid=%this_ssid:~1%"
echo %this_ssid%

rem disconnect from wlan
netsh wlan set profileparameter name="%this_ssid%" connectionmode=manual
netsh wlan disconnect
rem if [%2] EQU [] timeout /t %1
if [%2] EQU [] c:\hobl_bin\sleep\sleep.exe %1
if [%2] EQU [Disconnected] (
rem disconnect from wlan
netsh wlan set profileparameter name="%this_ssid%" connectionmode=manual
netsh wlan disconnect
)

rem Sleep for specified duration, if external button presser is used
if [%3] EQU [] c:\hobl_bin\cs_floor_resources\sleep.exe %1

if [%2] NEQ [] %dut_exec_path%\button\button.exe -s %button_delay%
netsh wlan set profileparameter name="%this_ssid%" connectionmode=auto nonBroadcast=yes
netsh wlan connect name="%this_ssid%"
rem Press button to go into standby for %button_delay% milliseconds, if software button being used
if [%3] NEQ [] %dut_exec_path%\button\button.exe -s %button_delay%

if [%2] EQU [Disconnected] (
netsh wlan set profileparameter name="%this_ssid%" connectionmode=auto nonBroadcast=yes
netsh wlan connect name="%this_ssid%"
)
10 changes: 10 additions & 0 deletions scenarios/windows/recharge.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Recharge(core.app_scenario.Scenario):
module = __module__.split('.')[-1]
# Set default parameters
Params.setDefault(module, 'resume_threshold', '100') # Percent battery level to charge to
Params.setDefault(module, 'post_charge_delay', '7200', 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.
Params.setDefault(module, 'leave_on_ac', '0', valOptions=["0", "1"])
Params.setDefault(module, 'monitor_only', '0', valOptions=["0", "1"]) # Do not turn on charger, just monitor battery level
Params.setDefault(module, 'check_smart_charge', '1', valOptions=["0", "1"])
Expand All @@ -30,6 +31,7 @@ class Recharge(core.app_scenario.Scenario):

# Get parameters
resume_threshold = Params.get(module, 'resume_threshold')
post_charge_delay = Params.get(module, 'post_charge_delay')
leave_on_ac = Params.get(module, 'leave_on_ac')
monitor_only = Params.get(module, 'monitor_only')
platform = Params.get('global', 'platform')
Expand Down Expand Up @@ -81,6 +83,14 @@ def runTest(self):

if batt_level >= 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
Expand Down
13 changes: 13 additions & 0 deletions scenarios/windows/standby.py
Original file line number Diff line number Diff line change
@@ -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
Loading