Files
MicroPythonOS/tests/base/keyboard_test_base.py
T
2026-01-13 00:38:17 +01:00

224 lines
6.8 KiB
Python

"""
Base class for keyboard tests in MicroPythonOS.
This class extends GraphicalTestBase with keyboard-specific functionality:
- Keyboard and textarea creation
- Keyboard button clicking
- Textarea text assertions
Usage:
from base import KeyboardTestBase
class TestMyKeyboard(KeyboardTestBase):
def test_typing(self):
keyboard, textarea = self.create_keyboard_scene()
self.click_keyboard_button("h")
self.click_keyboard_button("i")
self.assertTextareaText("hi")
"""
import lvgl as lv
from .graphical_test_base import GraphicalTestBase
class KeyboardTestBase(GraphicalTestBase):
"""
Base class for keyboard tests.
Extends GraphicalTestBase with keyboard-specific functionality.
Instance Attributes:
keyboard: The MposKeyboard instance (after create_keyboard_scene)
textarea: The textarea widget (after create_keyboard_scene)
"""
# Increase render iterations for keyboard tests
DEFAULT_RENDER_ITERATIONS = 10
def setUp(self):
"""Set up test fixtures."""
super().setUp()
self.keyboard = None
self.textarea = None
def create_keyboard_scene(self, initial_text="", textarea_width=200, textarea_height=30):
"""
Create a standard keyboard test scene with textarea and keyboard.
Args:
initial_text: Initial text in the textarea
textarea_width: Width of the textarea
textarea_height: Height of the textarea
Returns:
tuple: (keyboard, textarea)
"""
from mpos import MposKeyboard
# Create textarea
self.textarea = lv.textarea(self.screen)
self.textarea.set_size(textarea_width, textarea_height)
self.textarea.set_one_line(True)
self.textarea.align(lv.ALIGN.TOP_MID, 0, 10)
self.textarea.set_text(initial_text)
self.wait_for_render()
# Create keyboard and connect to textarea
self.keyboard = MposKeyboard(self.screen)
self.keyboard.set_textarea(self.textarea)
self.keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0)
self.wait_for_render()
return self.keyboard, self.textarea
def click_keyboard_button(self, button_text):
"""
Click a keyboard button by its text.
This uses the reliable click_keyboard_button helper which
directly manipulates the textarea for MposKeyboard instances.
Args:
button_text: The text of the button to click (e.g., "q", "a", "Enter")
Returns:
bool: True if button was clicked successfully
"""
from mpos import click_keyboard_button
if self.keyboard is None:
raise RuntimeError("No keyboard created. Call create_keyboard_scene() first.")
return click_keyboard_button(self.keyboard, button_text)
def get_textarea_text(self):
"""
Get the current text in the textarea.
Returns:
str: The textarea text
"""
if self.textarea is None:
raise RuntimeError("No textarea created. Call create_keyboard_scene() first.")
return self.textarea.get_text()
def set_textarea_text(self, text):
"""
Set the textarea text.
Args:
text: The text to set
"""
if self.textarea is None:
raise RuntimeError("No textarea created. Call create_keyboard_scene() first.")
self.textarea.set_text(text)
self.wait_for_render()
def clear_textarea(self):
"""Clear the textarea."""
self.set_textarea_text("")
def type_text(self, text):
"""
Type a string by clicking each character on the keyboard.
Args:
text: The text to type
Returns:
bool: True if all characters were typed successfully
"""
for char in text:
if not self.click_keyboard_button(char):
return False
return True
def assertTextareaText(self, expected, msg=None):
"""
Assert that the textarea contains the expected text.
Args:
expected: Expected text
msg: Optional failure message
"""
actual = self.get_textarea_text()
if msg is None:
msg = f"Textarea text mismatch. Expected '{expected}', got '{actual}'"
self.assertEqual(actual, expected, msg)
def assertTextareaEmpty(self, msg=None):
"""
Assert that the textarea is empty.
Args:
msg: Optional failure message
"""
if msg is None:
msg = f"Textarea should be empty, but contains '{self.get_textarea_text()}'"
self.assertEqual(self.get_textarea_text(), "", msg)
def assertTextareaContains(self, substring, msg=None):
"""
Assert that the textarea contains a substring.
Args:
substring: Substring to search for
msg: Optional failure message
"""
actual = self.get_textarea_text()
if msg is None:
msg = f"Textarea should contain '{substring}', but has '{actual}'"
self.assertIn(substring, actual, msg)
def get_keyboard_button_text(self, index):
"""
Get the text of a keyboard button by index.
Args:
index: Button index
Returns:
str: Button text, or None if not found
"""
if self.keyboard is None:
raise RuntimeError("No keyboard created. Call create_keyboard_scene() first.")
try:
return self.keyboard.get_button_text(index)
except:
return None
def find_keyboard_button_index(self, button_text):
"""
Find the index of a keyboard button by its text.
Args:
button_text: Text to search for
Returns:
int: Button index, or None if not found
"""
for i in range(100): # Check first 100 indices
text = self.get_keyboard_button_text(i)
if text is None:
break
if text == button_text:
return i
return None
def get_all_keyboard_buttons(self):
"""
Get all keyboard buttons as a list of (index, text) tuples.
Returns:
list: List of (index, text) tuples
"""
buttons = []
for i in range(100):
text = self.get_keyboard_button_text(i)
if text is None:
break
if text: # Skip empty strings
buttons.append((i, text))
return buttons