Initial import of ORISYS arm workstation
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
"""Exercise Qt and backend shutdown with no device transport in the UI."""
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
from station import runtime_client as runtime
|
||||
runtime.start(offline=True)
|
||||
import station.operator_app as ui
|
||||
app=ui.QApplication.instance();app.setFont(ui.QFont('Noto Sans SC',11));app.setStyleSheet(ui._STYLE)
|
||||
window=ui.StationApp();window.resize(1440,900);window.show()
|
||||
window._apply_theme('dark',persist=False)
|
||||
assert app.property('darkTheme') is True
|
||||
assert window._theme_selector.currentData()=='dark'
|
||||
window._apply_theme('light',persist=False)
|
||||
assert app.property('darkTheme') is False
|
||||
assert window._theme_selector.currentData()=='light'
|
||||
assert 'rclpy' not in sys.modules
|
||||
assert 'serial' not in sys.modules
|
||||
assert 'station.operator_console' not in sys.modules
|
||||
assert set(window._pages) == {'main','calibration','settings','ros_monitor'}
|
||||
# A photo must preserve the current RGB frame; no capture/device operation is needed.
|
||||
import tempfile
|
||||
from unittest.mock import patch
|
||||
sample=bytes([12,84,192])*(32*18)
|
||||
selected=next(cam for _page,cam,_label in window._camera_labels if cam.get('arm')==window._arm)
|
||||
with tempfile.TemporaryDirectory() as pictures:
|
||||
with patch.object(ui.Path,'home',return_value=ui.Path(pictures)), patch.object(ui.camera_view,'previews',return_value={selected['id']+'_color':(sample,32,18)}):
|
||||
window._take_photo()
|
||||
photos=list(ui.Path(pictures).rglob('*.png'))
|
||||
assert len(photos)==1
|
||||
image=ui.QImage(str(photos[0]))
|
||||
assert (image.width(),image.height())==(32,18)
|
||||
assert image.pixelColor(0,0).getRgb()[:3]==(12,84,192)
|
||||
window._open_camera(selected['id'])
|
||||
assert selected['id'] in window._camera_windows
|
||||
window._camera_windows[selected['id']].close()
|
||||
assert not window._camera_windows
|
||||
errors=[];ticks=[]
|
||||
duration=float(os.environ.get("ORISYS_GUI_TEST_SECONDS","2.2"))
|
||||
started=time.monotonic()
|
||||
frames=[bytes([v,40,80])*(320*180) for v in (30,70,120)]
|
||||
def tick():
|
||||
ticks.append(time.monotonic())
|
||||
if duration>10:
|
||||
if len(ticks)%100==0:
|
||||
window._show_page(("main","calibration")[(len(ticks)//100)%2])
|
||||
for key in ui.camera_view._PREVIEW_WANT:
|
||||
ui.camera_view._PREVIEW[key]=(frames[len(ticks)%3],320,180)
|
||||
ui.camera_view._META[key]=(320,180,20.)
|
||||
original=sys.excepthook
|
||||
def fail(*args): errors.append(str(args[1]));original(*args)
|
||||
sys.excepthook=fail
|
||||
beat=ui.QTimer();beat.timeout.connect(tick);beat.start(50)
|
||||
ui.QTimer.singleShot(200,lambda:window._start(lambda:(time.sleep(.7),{'ok':True,'message':'test'})[1],'test'))
|
||||
ui.QTimer.singleShot(500,lambda:window._show_page('calibration'))
|
||||
ui.QTimer.singleShot(1000,lambda:window._show_page('calibration'))
|
||||
ui.QTimer.singleShot(1500,lambda:window._show_page('ros_monitor'))
|
||||
ui.QTimer.singleShot(1900,lambda:window._show_page('main'))
|
||||
ui.QTimer.singleShot(round(duration*1000),window.close)
|
||||
ui.QTimer.singleShot(round((duration+15)*1000),app.quit)
|
||||
app.exec()
|
||||
assert len(ticks)>20,len(ticks)
|
||||
assert not errors,errors
|
||||
assert runtime._runtime is None
|
||||
assert not any(job.isRunning() for job in window._jobs.values())
|
||||
print('Qt responsive, no device modules, async task and graceful shutdown PASS',
|
||||
{'seconds':round(time.monotonic()-started,2),'ticks':len(ticks),
|
||||
'max_gap':round(max((b-a for a,b in zip(ticks,ticks[1:])),default=0),3),'errors':errors},flush=True)
|
||||
Reference in New Issue
Block a user