Re: TextCtrl: Emulating key events in wxPython 4


I am trying to test my dialogs in wxPython programmatically. For this, I am emitting the events of wxPython like this:

wx.PostEvent(element, wx.CommandEvent(wx.EVT_BUTTON._getEvtType(), element.GetId()))

Currently, I am stuck with emitting events for TextCtrls.

I have tried to...
* Post a key event.

charHookEvent = wx.KeyEvent(wx.EVT_CHAR_HOOK._getEvtType())
event = DummyKeyEvent(wx.EVT_KEY_DOWN._getEvtType())

The corresponding function in my dialog is called, however, the keycode is 0 and I have no chance to set it (I tried to override the KeyEvent and override the methods GetKeyCode() etc.)

I keep forgetting to do it, so I’ve added an issue to help me remember to
graft the setter methods for the (c++) public attributes back into the wx.KeyEvent class.

  • I tried to hand the KeyEvent over to .EmulateKeyPress, but this somehow does nothing.
  • I took a look at wx.UIActionSimulator. This works for me if the dialog is shown. But if the dialog is not shown, the function outputs text to my IDE (or whatever other application currently has the focus).

A third way would be to directly call SetValue, but than I may have a different behaviour of the dialog in my test. The disadvantage is, that I cannot test keyboard shortcuts like Ctrl+S etc. like this.

Is there anything I am missing?

Testing GUIs is hard. Most people (including me) would say that the best bet is
to fully decouple the UI from the rest of the application. IOW, make it
so your event handlers do nothing but invoke other parts of your application that are designed to be testable, using something like the mock package when needed to make the rest of the application think that the GUI is there. Then, if needed, you can do the opposite and mock the parts of the application API needed for testing the UI.

Of course that is not always easy to do, especially if there is already a lot of highly coupled UI code. If you’re on Windows then there are tools
like AutoHotKey that can be used to inject key and mouse events into an
application at a low enough level that wxWidgets, and the native controls themselves, can’t tell them apart from events coming from a real user. There are similar tools for the other platforms but I’m not recalling their names at the moment.