You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
224 lines
6.8 KiB
Python
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
|