mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 01:00:18 +02:00
The tabs UI (#4) runs Flatpak installs as server.start_job jobs, so a failed install answers 200 with a job id and reports the error on /api/job. The test now waits for the job instead of expecting an immediate 502. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
88 lines
4.6 KiB
Python
88 lines
4.6 KiB
Python
"""Status, Steam library, volume, clipboard, Flatpaks and the desktop capture,
|
|
through the server against the fake Frame."""
|
|
import unittest
|
|
|
|
import harness
|
|
from harness import api, ctl, finished, launches, ok, state, wait_for
|
|
|
|
harness.require()
|
|
|
|
|
|
class Device(harness.FrameTestCase):
|
|
def test_status(self):
|
|
s = ok('GET', '/api/status')
|
|
self.assertEqual(s['hostname'], 'frame')
|
|
self.assertEqual(s['os'], {'version': '0.3.0', 'build': '20260922.6101926', 'variant': 'vr'})
|
|
b = s['battery']
|
|
self.assertEqual((b['percent'], b['status'], b['health']), (76, 'Charging', 'Good'))
|
|
self.assertAlmostEqual(b['watts'], 9.62, places=1)
|
|
self.assertAlmostEqual(b['tempC'], 31.2, places=3)
|
|
self.assertEqual(s['power'], {'type': 'C PD [PD_PPS]', 'watts': 20.0})
|
|
self.assertEqual(s['temp'], 41.5)
|
|
self.assertEqual(s['wifi'], {'ssid': 'Fake:Frame Wi-Fi', 'signal': 72})
|
|
self.assertEqual(s['volume'], {'level': 0.4, 'muted': False})
|
|
self.assertEqual(s['services'], {'steamvr': True, 'desktop': True, 'lepton': False, 'rdp': False})
|
|
# Runtimes and Lepton are Steam "apps" too; the status hides them.
|
|
self.assertEqual([g['name'] for g in s['games']], ['Beat Saber'])
|
|
self.assertIsNotNone(s['disk']['home'])
|
|
|
|
ctl('battery', 'capacity=15', 'status=Discharging', 'current_now=-900000')
|
|
b = ok('GET', '/api/status')['battery']
|
|
self.assertEqual((b['percent'], b['status']), (15, 'Discharging'))
|
|
self.assertLess(b['watts'], 0)
|
|
|
|
def test_volume_and_mute(self):
|
|
ok('POST', '/api/volume', {'level': 0.55, 'muted': True})
|
|
self.assertEqual(state()['volume'], {'level': 0.55, 'muted': True})
|
|
self.assertEqual(ok('GET', '/api/status')['volume'], {'level': 0.55, 'muted': True})
|
|
status, out, _ = api('POST', '/api/volume', {'level': 2})
|
|
self.assertEqual(status, 400, out)
|
|
|
|
def test_clipboard_goes_to_klipper(self):
|
|
text = 'héllo from the e2e tests\nline two, with a trailing newline\n'
|
|
out = ok('POST', '/api/clipboard', {'text': text})
|
|
# ${#text} counts bytes or characters depending on the session's locale.
|
|
self.assertRegex(out['message'], r'^copied via Klipper \(\d+ chars\)$')
|
|
self.assertEqual(state()['clipboard'], [text])
|
|
|
|
def test_flatpak_install_and_remove(self):
|
|
# Installs run as background jobs (server.start_job); uninstall answers at once.
|
|
job = finished(ok('POST', '/api/flatpak', {'id': 'org.videolan.VLC', 'action': 'install'}))
|
|
self.assertIsNone(job['error'], job)
|
|
self.assertEqual([f['id'] for f in ok('GET', '/api/status')['flatpaks']], ['org.videolan.VLC'])
|
|
ok('POST', '/api/flatpak', {'id': 'org.videolan.VLC', 'action': 'uninstall'})
|
|
self.assertEqual(state()['flatpaks'], [])
|
|
job = finished(ok('POST', '/api/flatpak', {'id': 'org.example.missing', 'action': 'install'}))
|
|
self.assertIn('Nothing matches org.example.missing', job['error'])
|
|
|
|
def test_desktop_capture(self):
|
|
status, png, headers = api('GET', '/api/screenshot')
|
|
self.assertEqual(status, 200, png)
|
|
self.assertTrue(png.startswith(b'\x89PNG\r\n\x1a\n'))
|
|
self.assertEqual(headers.get('X-Capture-Source'), 'gamescope')
|
|
|
|
def test_steam_library_and_installs(self):
|
|
owned = ok('GET', '/api/steam/owned')
|
|
self.assertEqual(owned['country'], 'AU')
|
|
games = {g['id']: g for g in owned['games']}
|
|
self.assertEqual(set(games), {2379780, 274190, 620980})
|
|
self.assertEqual((games[2379780]['frame'], games[620980]['installed']), (3, True))
|
|
# Balatro queues at once; Broforce stops at the options dialog, which
|
|
# frame_steam.py accepts with ContinueInstall().
|
|
for appid, name in ((2379780, 'Balatro'), (274190, 'Broforce')):
|
|
out = ok('POST', '/api/steam', {'appid': appid, 'action': 'install'})
|
|
self.assertEqual(out, {'state': 'downloading', 'message': f'{name} is queued to download on the Frame'})
|
|
self.assertEqual(ok('GET', '/api/steam/owned')['download']['appid'], 274190)
|
|
|
|
def test_launch_and_store_page(self):
|
|
ok('POST', '/api/launch', {'appid': 620980})
|
|
run = wait_for(lambda: launches('rungameid'), 10, 'the launch to reach Steam')[-1]
|
|
self.assertEqual((run['appid'], run['started']), (620980, True))
|
|
ok('POST', '/api/steam', {'appid': 1145360, 'action': 'store'})
|
|
wait_for(lambda: state()['steam']['pages'], 10, 'the store page')
|
|
self.assertEqual(state()['steam']['pages'][0]['title'], 'Hades on Steam')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|