Skip to content

Commit 428ad5e

Browse files
Add tests/test_graphical_keyboard_mode_switch.py
1 parent 01c286e commit 428ad5e

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
Test for MposKeyboard mode switching crash.
3+
4+
This test reproduces the crash that occurs when clicking the UP arrow
5+
to switch to uppercase mode in MposKeyboard.
6+
7+
Usage:
8+
Desktop: ./tests/unittest.sh tests/test_graphical_keyboard_mode_switch.py
9+
Device: ./tests/unittest.sh tests/test_graphical_keyboard_mode_switch.py --ondevice
10+
"""
11+
12+
import unittest
13+
import lvgl as lv
14+
from mpos.ui.keyboard import MposKeyboard
15+
from graphical_test_helper import wait_for_render
16+
17+
18+
class TestKeyboardModeSwitch(unittest.TestCase):
19+
"""Test keyboard mode switching doesn't crash."""
20+
21+
def setUp(self):
22+
"""Set up test fixtures."""
23+
self.screen = lv.obj()
24+
self.screen.set_size(320, 240)
25+
26+
# Create textarea
27+
self.textarea = lv.textarea(self.screen)
28+
self.textarea.set_size(280, 40)
29+
self.textarea.align(lv.ALIGN.TOP_MID, 0, 10)
30+
self.textarea.set_one_line(True)
31+
32+
# Load screen
33+
lv.screen_load(self.screen)
34+
wait_for_render(5)
35+
36+
def tearDown(self):
37+
"""Clean up."""
38+
lv.screen_load(lv.obj())
39+
wait_for_render(5)
40+
41+
def test_switch_to_uppercase_with_symbol_up(self):
42+
"""
43+
Test switching to uppercase mode.
44+
45+
This reproduces the crash that occurred when clicking the UP arrow button.
46+
The bug was that set_mode() was called without set_map() first.
47+
"""
48+
print("\n=== Testing uppercase mode switch ===")
49+
50+
# Create keyboard
51+
keyboard = MposKeyboard(self.screen)
52+
keyboard.set_textarea(self.textarea)
53+
keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0)
54+
wait_for_render(10)
55+
56+
# Keyboard starts in lowercase mode
57+
print("Initial mode: MODE_LOWERCASE")
58+
59+
# Find the UP symbol button by searching all buttons
60+
up_button_index = None
61+
for i in range(100): # Try up to 100 buttons
62+
try:
63+
text = keyboard.get_button_text(i)
64+
if text == lv.SYMBOL.UP:
65+
up_button_index = i
66+
print(f"Found UP symbol at button index {i}")
67+
break
68+
except:
69+
pass
70+
71+
self.assertIsNotNone(up_button_index, "Should find UP symbol button")
72+
73+
# Test mode switching (this is what happens when the user clicks UP)
74+
print("Switching to uppercase mode...")
75+
try:
76+
keyboard.set_mode(MposKeyboard.MODE_UPPERCASE)
77+
wait_for_render(5)
78+
print("SUCCESS: No crash when switching to uppercase!")
79+
80+
# Verify we're now in uppercase mode by checking the button changed
81+
down_button_text = keyboard.get_button_text(up_button_index)
82+
print(f"After switch, button {up_button_index} text: {down_button_text}")
83+
self.assertEqual(down_button_text, lv.SYMBOL.DOWN,
84+
"Should show DOWN symbol in uppercase mode")
85+
86+
# Switch back to lowercase
87+
keyboard.set_mode(MposKeyboard.MODE_LOWERCASE)
88+
wait_for_render(5)
89+
up_button_text = keyboard.get_button_text(up_button_index)
90+
self.assertEqual(up_button_text, lv.SYMBOL.UP,
91+
"Should show UP symbol in lowercase mode")
92+
93+
except Exception as e:
94+
self.fail(f"CRASH: Switching to uppercase caused exception: {e}")
95+
96+
def test_switch_modes_multiple_times(self):
97+
"""
98+
Test switching between all keyboard modes multiple times.
99+
100+
Tests the full mode switching cycle to ensure all modes work.
101+
"""
102+
print("\n=== Testing multiple mode switches ===")
103+
104+
keyboard = MposKeyboard(self.screen)
105+
keyboard.set_textarea(self.textarea)
106+
keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0)
107+
wait_for_render(10)
108+
109+
modes_to_test = [
110+
(MposKeyboard.MODE_UPPERCASE, "MODE_UPPERCASE"),
111+
(MposKeyboard.MODE_LOWERCASE, "MODE_LOWERCASE"),
112+
(MposKeyboard.MODE_NUMBERS, "MODE_NUMBERS"),
113+
(MposKeyboard.MODE_SPECIALS, "MODE_SPECIALS"),
114+
(MposKeyboard.MODE_LOWERCASE, "MODE_LOWERCASE (again)"),
115+
]
116+
117+
for mode, mode_name in modes_to_test:
118+
print(f"Switching to {mode_name}...")
119+
try:
120+
keyboard.set_mode(mode)
121+
wait_for_render(5)
122+
print(f" SUCCESS: Switched to {mode_name}")
123+
except Exception as e:
124+
self.fail(f" CRASH: Switching to {mode_name} caused exception: {e}")
125+
126+
127+
if __name__ == "__main__":
128+
unittest.main()

0 commit comments

Comments
 (0)