subiquity/subiquitycore/testing/view_helpers.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

114 lines
3.2 KiB
Python
Raw Normal View History

import asyncio
2017-11-07 22:59:13 +00:00
import re
from typing import Type
2023-07-25 21:26:25 +00:00
2017-11-07 22:59:13 +00:00
import urwid
from subiquitycore.ui.frame import SubiquityCoreUI
from subiquitycore.ui.stretchy import Stretchy, StretchyOverlay
2018-07-06 02:44:19 +00:00
2017-12-21 01:41:05 +00:00
def find_with_pred(w, pred, return_path=False):
def _walk(w, path):
if not isinstance(w, urwid.Widget):
raise RuntimeError("_walk walked to non-widget %r via %r" % (w, path))
2017-11-07 22:59:13 +00:00
if pred(w):
2017-12-21 01:41:05 +00:00
return w, path
2017-11-07 22:59:13 +00:00
if hasattr(w, "_wrapped_widget"):
2017-12-21 01:41:05 +00:00
return _walk(w._wrapped_widget, (w,) + path)
2017-11-07 22:59:13 +00:00
if hasattr(w, "original_widget"):
2017-12-21 01:41:05 +00:00
return _walk(w.original_widget, (w,) + path)
2017-11-07 22:59:13 +00:00
if isinstance(w, urwid.ListBox):
for w in w.body:
2017-12-21 01:41:05 +00:00
r, p = _walk(w, (w,) + path)
2017-11-07 22:59:13 +00:00
if r:
2017-12-21 01:41:05 +00:00
return r, p
elif isinstance(w, urwid.Frame):
for w, _ in w.contents.values():
r, p = _walk(w, (w,) + path)
if r:
return r, p
2017-11-07 22:59:13 +00:00
elif hasattr(w, "contents"):
contents = w.contents
for w, _ in contents:
2017-12-21 01:41:05 +00:00
r, p = _walk(w, (w,) + path)
2017-11-07 22:59:13 +00:00
if r:
2017-12-21 01:41:05 +00:00
return r, p
2018-07-06 02:44:19 +00:00
elif isinstance(w, StretchyOverlay):
r, p = _walk(w.top_w, (w,) + path)
if r:
return r, p
2017-12-21 01:41:05 +00:00
return None, None
2023-07-25 21:26:25 +00:00
2017-12-21 01:41:05 +00:00
r, p = _walk(w, ())
if return_path:
return r, p
else:
return r
2017-11-07 22:59:13 +00:00
2017-12-21 01:41:05 +00:00
def find_button_matching(w, pat, return_path=False):
2017-11-07 22:59:13 +00:00
def pred(w):
return isinstance(w, urwid.Button) and re.match(pat, w.label)
2023-07-25 21:26:25 +00:00
2017-12-21 01:41:05 +00:00
return find_with_pred(w, pred, return_path)
2017-11-07 22:59:13 +00:00
2017-11-07 22:59:13 +00:00
def click(but):
but._emit("click")
2017-11-07 22:59:13 +00:00
def keypress(w, key, size=(30, 1)):
w.keypress(size, key)
2017-11-07 22:59:13 +00:00
def get_focus_path(w):
path = []
while True:
path.append(w)
if isinstance(w, urwid.ListBox) and (w.set_focus_pending == "first selectable"):
2017-12-03 21:29:06 +00:00
for w2 in w.body:
if w2.selectable():
w = w2
break
else:
break
2017-11-07 22:59:13 +00:00
if w.focus is not None:
w = w.focus
elif hasattr(w, "_wrapped_widget"):
w = w._wrapped_widget
elif hasattr(w, "original_widget"):
w = w.original_widget
else:
break
return path
def enter_data(form, data):
for k, v in data.items():
bf = getattr(form, k)
assert bf.enabled, "%s is not enabled" % (k,)
bf.value = v
async def wait_for_overlay(
ui: SubiquityCoreUI, overlay_type: Type[Stretchy], *, timeout=None, step=0.01
) -> Stretchy:
"""Wait until an overlay of the specified type gets displayed on the
screen and return it. If timeout is hit before the overlay is displayed, an
asyncio.TimeoutError will be raised. When timeout is set to None, we will
wait forever."""
if timeout is not None:
task = wait_for_overlay(ui, overlay_type)
return await asyncio.wait_for(task, timeout=timeout)
while True:
try:
stretchy = ui.body._w.stretchy
except AttributeError:
pass
else:
if isinstance(stretchy, overlay_type):
return stretchy
await asyncio.sleep(step)