GuiTestContextKeyEventTests.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. using TerminalGuiFluentTesting;
  2. using TerminalGuiFluentTestingXunit;
  3. using Xunit.Abstractions;
  4. namespace IntegrationTests.FluentTests;
  5. /// <summary>
  6. /// Integration tests for GuiTestContext keyboard event handling (EnqueueKeyEvent).
  7. /// </summary>
  8. public class GuiTestContextKeyEventTests (ITestOutputHelper outputHelper)
  9. {
  10. private readonly TextWriter _out = new TestOutputWriter (outputHelper);
  11. [Theory]
  12. [ClassData (typeof (TestDrivers))]
  13. public void QuitKey_ViaApplication_Stops (TestDriver d)
  14. {
  15. using GuiTestContext context = With.A<Window> (40, 10, d);
  16. Assert.True (context.App?.Current!.Running);
  17. Toplevel? top = context.App?.Current;
  18. context.Then ((_) => context!.App?.Keyboard.RaiseKeyDownEvent (Application.QuitKey));
  19. Assert.False (top!.Running);
  20. }
  21. [Theory]
  22. [ClassData (typeof (TestDrivers))]
  23. public void QuitKey_ViaEnqueueKey_Stops (TestDriver d)
  24. {
  25. using GuiTestContext context = With.A<Window> (40, 10, d, _out);
  26. Assert.True (context.App?.Current!.Running);
  27. Toplevel? top = context.App?.Current;
  28. context.EnqueueKeyEvent (Application.QuitKey);
  29. Assert.False (top!.Running);
  30. }
  31. [Theory]
  32. [ClassData (typeof (TestDrivers))]
  33. public void EnqueueKey_AfterResizeConsole_StillWorks (TestDriver d)
  34. {
  35. var keyReceived = false;
  36. var view = new View { CanFocus = true };
  37. view.KeyDown += (s, e) => keyReceived = true;
  38. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  39. .Add (view)
  40. .Then ((_) => view.SetFocus ())
  41. .ResizeConsole (50, 20)
  42. .EnqueueKeyEvent (Key.A);
  43. Assert.True (keyReceived);
  44. }
  45. [Theory]
  46. [ClassData (typeof (TestDrivers))]
  47. public void EnqueueKey_Backspace_DeletesCharacter (TestDriver d)
  48. {
  49. var textField = new TextField { Text = "TEST", Width = 20 };
  50. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  51. .Add (textField)
  52. .Focus (textField)
  53. .Then ((_) => textField.CursorPosition = textField.Text.Length)
  54. .EnqueueKeyEvent (Key.Backspace)
  55. .EnqueueKeyEvent (Key.Backspace);
  56. Assert.Equal ("TE", textField.Text);
  57. }
  58. [Theory]
  59. [ClassData (typeof (TestDrivers))]
  60. public void EnqueueKey_ChainedWithOtherOperations_WorksCorrectly (TestDriver d)
  61. {
  62. var textField = new TextField { Width = 20 };
  63. var clickedCount = 0;
  64. var button = new Button { Text = "Click Me" };
  65. button.Accepting += (s, e) => clickedCount++;
  66. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  67. .Add (textField)
  68. .Add (button)
  69. .Then ((_) => textField.SetFocus ())
  70. .EnqueueKeyEvent (Key.T.WithShift)
  71. .EnqueueKeyEvent (Key.E)
  72. .EnqueueKeyEvent (Key.S)
  73. .EnqueueKeyEvent (Key.T)
  74. .AssertEqual ("Test", textField.Text)
  75. .EnqueueKeyEvent (Key.Tab)
  76. .Then ((_) => Assert.True (button.HasFocus))
  77. .EnqueueKeyEvent (Key.Enter)
  78. .AssertEqual (1, clickedCount);
  79. }
  80. [Theory]
  81. [ClassData (typeof (TestDrivers))]
  82. public void EnqueueKey_EnqueuesKeyAndProcessesIt (TestDriver d)
  83. {
  84. var keyReceived = false;
  85. var receivedKey = Key.Empty;
  86. var view = new View { CanFocus = true };
  87. view.KeyDown += (s, e) =>
  88. {
  89. keyReceived = true;
  90. receivedKey = e;
  91. };
  92. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  93. .Add (view)
  94. .Then ((_) => view.SetFocus ())
  95. .EnqueueKeyEvent (Key.A);
  96. Assert.True (keyReceived, "Key was not received by the view");
  97. Assert.Equal (Key.A, receivedKey);
  98. }
  99. [Theory]
  100. [ClassData (typeof (TestDrivers))]
  101. public void EnqueueKey_FunctionKeys_ProcessesCorrectly (TestDriver d)
  102. {
  103. List<Key> keysReceived = [];
  104. var view = new View { CanFocus = true };
  105. view.KeyDown += (s, e) => keysReceived.Add (e);
  106. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  107. .Add (view)
  108. .Then ((_) => view.SetFocus ())
  109. .EnqueueKeyEvent (Key.F1)
  110. .EnqueueKeyEvent (Key.F5)
  111. .EnqueueKeyEvent (Key.F12);
  112. Assert.Equal (3, keysReceived.Count);
  113. Assert.Equal (Key.F1, keysReceived [0]);
  114. Assert.Equal (Key.F5, keysReceived [1]);
  115. Assert.Equal (Key.F12, keysReceived [2]);
  116. }
  117. [Theory]
  118. [ClassData (typeof (TestDrivers))]
  119. public void EnqueueKey_MultipleKeys_ProcessesInOrder (TestDriver d)
  120. {
  121. List<Key> keysReceived = [];
  122. var view = new View { CanFocus = true };
  123. view.KeyDown += (s, e) => keysReceived.Add (e);
  124. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  125. .Add (view)
  126. .Then ((_) => view.SetFocus ())
  127. .EnqueueKeyEvent (Key.A)
  128. .EnqueueKeyEvent (Key.B)
  129. .EnqueueKeyEvent (Key.C);
  130. Assert.Equal (3, keysReceived.Count);
  131. Assert.Equal (Key.A, keysReceived [0]);
  132. Assert.Equal (Key.B, keysReceived [1]);
  133. Assert.Equal (Key.C, keysReceived [2]);
  134. }
  135. [Theory]
  136. [ClassData (typeof (TestDrivers))]
  137. public void EnqueueKey_NavigationKeys_ChangeFocus (TestDriver d)
  138. {
  139. var view1 = new View { Id = "view1", CanFocus = true };
  140. var view2 = new View { Id = "view2", CanFocus = true };
  141. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  142. .Add (view1)
  143. .Add (view2)
  144. .Then ((_) => view1.SetFocus ())
  145. .AssertTrue (view1.HasFocus)
  146. .AssertFalse (view2.HasFocus)
  147. .EnqueueKeyEvent (Key.Tab)
  148. .AssertFalse (view1.HasFocus)
  149. .AssertTrue (view2.HasFocus)
  150. .EnqueueKeyEvent (Key.Tab.WithShift)
  151. .AssertTrue (view1.HasFocus)
  152. .AssertFalse (view2.HasFocus);
  153. }
  154. [Theory]
  155. [ClassData (typeof (TestDrivers))]
  156. public void EnqueueKey_NumericKeys_ProcessesCorrectly (TestDriver d)
  157. {
  158. var textField = new TextField { Width = 20 };
  159. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  160. .Add (textField)
  161. .Then ((_) => textField.SetFocus ())
  162. .EnqueueKeyEvent (Key.D1)
  163. .EnqueueKeyEvent (Key.D2)
  164. .EnqueueKeyEvent (Key.D3)
  165. .EnqueueKeyEvent (Key.D4)
  166. .EnqueueKeyEvent (Key.D5);
  167. Assert.Equal ("12345", textField.Text);
  168. }
  169. [Theory]
  170. [ClassData (typeof (TestDrivers))]
  171. public void EnqueueKey_RapidSequence_ProcessesAllKeys (TestDriver d)
  172. {
  173. List<Key> keysReceived = [];
  174. var view = new View { CanFocus = true };
  175. view.KeyDown += (s, e) => keysReceived.Add (e);
  176. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  177. .Add (view)
  178. .Then ((_) => view.SetFocus ());
  179. // Send 10 keys rapidly
  180. for (var i = 0; i < 10; i++)
  181. {
  182. context.EnqueueKeyEvent ((Key)(Key.A.KeyCode + (uint)i));
  183. }
  184. Assert.Equal (10, keysReceived.Count);
  185. for (var i = 0; i < 10; i++)
  186. {
  187. Assert.Equal ((Key)(Key.A.KeyCode + (uint)i), keysReceived [i]);
  188. }
  189. }
  190. [Theory]
  191. [ClassData (typeof (TestDrivers))]
  192. public void EnqueueKey_SpecialKeys_ProcessesCorrectly (TestDriver d)
  193. {
  194. List<Key> keysReceived = [];
  195. var view = new View { CanFocus = true };
  196. view.KeyDown += (s, e) => keysReceived.Add (e);
  197. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  198. .Add (view)
  199. .Then ((_) => view.SetFocus ())
  200. .EnqueueKeyEvent (Key.Enter)
  201. .EnqueueKeyEvent (Key.Tab)
  202. .EnqueueKeyEvent (Key.CursorUp)
  203. .EnqueueKeyEvent (Key.CursorDown)
  204. .EnqueueKeyEvent (Key.Esc);
  205. Assert.Equal (5, keysReceived.Count);
  206. Assert.Equal (Key.Enter, keysReceived [0]);
  207. Assert.Equal (Key.Tab, keysReceived [1]);
  208. Assert.Equal (Key.CursorUp, keysReceived [2]);
  209. Assert.Equal (Key.CursorDown, keysReceived [3]);
  210. Assert.Equal (Key.Esc, keysReceived [4]);
  211. }
  212. [Theory]
  213. [ClassData (typeof (TestDrivers))]
  214. public void EnqueueKey_WithListView_NavigatesItems (TestDriver d)
  215. {
  216. var listView = new ListView
  217. {
  218. Width = Dim.Fill (),
  219. Height = Dim.Fill ()
  220. };
  221. listView.SetSource (["Item1", "Item2", "Item3", "Item4", "Item5"]);
  222. listView.SelectedItem = 0;
  223. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  224. .Add (listView)
  225. .Then ((_) => listView.SetFocus ())
  226. .AssertEqual (0, listView.SelectedItem)
  227. .EnqueueKeyEvent (Key.CursorDown)
  228. .AssertEqual (1, listView.SelectedItem)
  229. .EnqueueKeyEvent (Key.CursorDown)
  230. .AssertEqual (2, listView.SelectedItem)
  231. .EnqueueKeyEvent (Key.CursorUp)
  232. .AssertEqual (1, listView.SelectedItem);
  233. }
  234. [Theory]
  235. [ClassData (typeof (TestDrivers))]
  236. public void EnqueueKey_WithModifiers_ProcessesCorrectly (TestDriver d)
  237. {
  238. var keyReceived = false;
  239. var receivedKey = Key.Empty;
  240. var view = new View { CanFocus = true };
  241. view.KeyDown += (s, e) =>
  242. {
  243. keyReceived = true;
  244. receivedKey = e;
  245. };
  246. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  247. .Add (view)
  248. .Then ((_) => view.SetFocus ())
  249. .EnqueueKeyEvent (Key.A.WithCtrl);
  250. Assert.True (keyReceived);
  251. Assert.Equal (Key.A.WithCtrl, receivedKey);
  252. Assert.True (receivedKey.IsCtrl);
  253. }
  254. [Theory]
  255. [ClassData (typeof (TestDrivers))]
  256. public void EnqueueKey_WithTextField_UpdatesText (TestDriver d)
  257. {
  258. var textField = new TextField { Width = 20 };
  259. using GuiTestContext context = With.A<Window> (40, 10, d, _out)
  260. .Add (textField)
  261. .EnqueueKeyEvent (Key.H.WithShift)
  262. .EnqueueKeyEvent (Key.E)
  263. .EnqueueKeyEvent (Key.L)
  264. .EnqueueKeyEvent (Key.L)
  265. .EnqueueKeyEvent (Key.O);
  266. //Assert.Equal ("Hello", textField.Text);
  267. }
  268. }