Add an On/Off/Reset bar above the screen

Buttons sit above the LCD as asked, with a state label that turns green when the
guest is up. Powered off dims the panel via a screen-off class, so a dark screen
is the signal rather than a frozen last frame.

Off asks for confirmation: it ends the guest, and a stray click should not do that
silently. Buttons disable while a power action is in flight, since On and Off take
a couple of seconds and a double click would race.

The stream is restarted after every power action. The old multipart response ends
when the emulator goes away, so without a fresh src the image would stay blank
after On.

Refusals are surfaced in the status line rather than swallowed -- that is how the
409 for an adopted emulator becomes visible instead of looking like a dead button.

49 unit tests, and the generated page passes node --check.
This commit is contained in:
mckero committed 2026-08-28 06:02:30 +01:00
1 parent 699561794a
commit 6a9cf9f28a
2 files changed
+81 -2

No files matched your search

+26
View File
@@ -411,5 +411,31 @@ class TestKeyWhenPoweredOff(unittest.TestCase):
self.assertEqual(resp.status_code, 409)
class TestPowerBar(unittest.TestCase):
def setUp(self):
_, http = make_app()
self.body = http.get("/").get_data(as_text=True)
def test_has_power_buttons(self):
for action in ("on", "off", "reset"):
self.assertIn(f'data-power="{action}"', self.body)
def test_power_bar_is_above_the_screen(self):
"""The user asked for it on top."""
self.assertLess(self.body.index('data-power="on"'),
self.body.index('id="screen"'))
def test_power_off_asks_for_confirmation(self):
"""Off kills the emulator; a stray click should not do that silently."""
self.assertIn("confirm(", self.body)
def test_shows_the_powered_state(self):
self.assertIn("powerstate", self.body)
def test_dims_the_screen_when_off(self):
"""A dark screen is the signal that the machine is off."""
self.assertIn("screen-off", self.body)
if __name__ == "__main__":
unittest.main()