Synthesizing events for testing a GUI in gtk3

Hi –

In the old gtk+2 version of our program, we have GUI test code that can be run either in record or replay mode. In record mode it records all GdkEvents and gtk signals in a log file. The log file can be annotated with tests and then run in replay mode, ensuring that the GUI is working as it should. Because recording and replaying is on the event and signal level instead of using pixels and mouse clicks, the tests work even if they’re replayed on a screen with different resolution or different widget sizes. They don’t break even if new objects are added to the GUI. (There’s some documentation at https://www.ctcms.nist.gov/oof/gtklogger/, if you’re interested.)

Doing this relies on being able to regenerate the GdkEvents from the data in the log file, and then executing them with GtkWidget.event() or Gtk.main_do_event(). I’m finding this much harder to do with gtk3 than it was with gtk+2. For example, in gtk+2 I could ignore the device member of the event structure, but gtk3 complains if it’s not set. It looks like this might work, but it feels sketchy:

event = Gdk.Event.new(Gdk.EventType.BUTTON_PRESS)
event.set_device(Gdk.Display.get_default().list_devices()[0])

Some (all?) events also need a GdkSeat, but I don’t see how to get a value for that or how to set it.

Is there a proper way to synthesize GdkEvents from logged data? I’ve seen references to other techniques but I haven’t seen any that do what I want.

Thanks.
– Steve

Whatever I was doing to get error messages about GdkSeat seems to have gone away… The bigger question about how to synthesize events safely is still open.

– Steve

The current “best practice” for UI testing does not go through event synthesis, because that can’t work across process boundaries, and because of timing and complex event chains: simulating a “click” on a button involves two events, but it could also involve a series of motion events that move out and back in, and those generate additional crossing events inside GTK itself. GTK has some testing API for its own test suites, but I would not recommend its use outside of the toolkit itself

Typically, UI testing frameworks use the accessibility stack: Dogtail is one of them. Ideally, we’d like to move that functionality out of the accessibility realm, because it’s semantically very different; but for testing existing applications, it’s still relevant.

It looks like Dogtail needs the gnome desktop. Can it be run independently from that? Although we are using gtk3 widgets, our program isn’t tied to any particular platform.

Being limited to a single process isn’t a problem for us. Would event timing be more of an issue in gtk3 than it is in gtk+2? Our gtk+2 version has a checkpoint mechanism that ensures that synthesized events occur in the correct order if there are multiple execution threads.

– Steve

No, it does not need the GNOME desktop; it needs the various components of the accessibility infrastructure, which are generic, and a dependency of the GNOME desktop (not the other way around). It’s not going to be usable outside of Linux/Unix, though, because the accessibility stack in GTK has not been ported to other windowing systems.

You can look at the GTK testing API, if you think it’s enough.

I see. I first tried dogtail on macOS and the packages it needed didn’t seem to be available there. It does better on an Ubuntu VM. It’s still not clear to me that it does what I need it to, but I’ll look at it some more. One thing that it doesn’t do as well as our old gtk+2 code is that it requires time delays to be inserted to avoid race conditions, while our code could insert checkpoints to avoid them.

Is the GTK testing API that you’re referring to this one? https://developer.gnome.org/gtk3/stable/gtk3-Testing.html

If I were to insist on writing event and signal based testing routines, is there somebody who could answer questions and give me feedback? I expect I’ll need to know if certain data in an event structure is crucial, or if I’m making bad assumptions about something (such as, if the way I set the device in the example above is safe).

Thanks.

– Steve

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.