For automated unit testing of custom UI elements it would be helpful to simulate certain actions a user would take - one being the click/tap on a certain UI element. How would one do this exactly?
I have found this documentation which unfortunately did not help me very much. The example for a KeyDown event simply reports 'EventType' does not contain a definition for 'KeyDownEvent' in Unity 2021.2.19f1.
But even if this was working - how would synthesizing a click event look like?
Thank you for the very fast response, @benoitm-unity ! It worked indeed as expected. For others if they run into problems: I had pretty much the same, but I had
evt.target = uielement;
set, because, idk, it seemed plausible to me. With this property set it didnât work though.
You have right you can fix it with that line or by changing âuielementâ in âuielement.SendEvent(mouseDownEvent and mouseUpEvent);â by the root element of the windows/panel like âmyroot.SendEventâŚâ"
What if I want to simulate a mouse click at the position of an element to test that it actually receives the click, i.e., is not covered by another element or something else?
Hi there, other Benoit here with some more answers.
setting evt.target = uielement is not something you should do in general, as it forces the event to go directly to that element regardless of its position. Also itâs not super reliable, each event type has a potentially different policy on how to calculate their target and how to deal with a pre-set target like that. Some events will just ignore their pre-set target and recalculate their own target, and some other events will use it even if it doesnât really make sense (pointer events on an element that has pickingMode = Ignore, for example).
Second point. The API for sending an event is someElement.SendEvent(someEvent), but that does not set the target of someEvent to someElement. In fact, the only thing it does is it sends the event to the elementâs panel, where it will search for a proper target and propagate though the hierarchy accordingly. It could end up targetting some other element and completely ignore someElement.
@seyfe if you want to test that your element actually receives the click, just donât set evt.target (or set it to null, which it is by default) but do set the position where the click is happening. Then you can send the event using panel.visualTree.SendEvent(evt) if you know what panel you want to send it to, just so youâre clear youâre not sending it to the element itself but really youâre sending it to the entire panel. What youâre trying to do is pretty much the default behavior for all events, i.e. not setting the target will make it choose its own target thus testing if the element is covered by another element etc.
Hi other Benoit! Thanks for clarifying things. Also, I would support your fight for Markdown usage in the forums
One thing to add to the answer of @benoitm-unity : As far as I understand, if you were to write a click method on arbitrary objects, you might want to use uielement.worldBound.center instead of uielement.layout.center to get the coordinates of the click position right.
Iâm trying to simulate ClickEvent on certain mouse position using the above approach. With MouseUpEvent/MouseDownEvent everything works as described, but with ClickEvent it always triggering on the element under current mouse position.
Is this behaviour expected, or am I doing something wrong?
var root = uiDocument.rootVisualElement;
var evt = new Event()
{
type = EventType.MouseUp,
mousePosition = new Vector2(-100, -100),
button = 0,
pointerType = UnityEngine.PointerType.Mouse,
};
using (EventBase clickEvent = ClickEvent.GetPooled(evt))
{
root.panel.visualTree.SendEvent(clickEvent);
}