Hey developers,
I’m trying to automate UI integration tests by emulating actual user clicks on UI elements. Why do I need this? Edge cases of type: ‘click on the control, but release mouse button outside of it’, or ‘click on this control, nested inside of another control, nested inside of yet another one’ are difficult co capture with simple unit tests.
It’s relatively straightforward to run these tests with native Eto controls. But Eto.Drawable
is not compatible with automation. That’s unfortunate, since all my custom controls are based on Eto.Drawable
…
Do you know of any way of making the automation framework aware of the Drawable
control?
I’m tagging @curtisw and @fraguada but would appreciate input from anyone knowledgeable in this matter.
My test panel is super simple:
var mainLayout = new DynamicLayout() { Padding = 10, Spacing = new Size(0, 6) };
var myDrawable = new Drawable();
myDrawable.Size = new Size(-1, 100);
myDrawable.BackgroundColor = Eto.Drawing.Colors.Red;
myDrawable.ID = "MyDrawable";
var myButton = new Button();
myButton.Text = "MyButton";
var myPanel = new Panel();
myPanel.Size = new Size(-1, 100);
myPanel.BackgroundColor = Eto.Drawing.Colors.Blue;
mainLayout.AddRow(myButton);
mainLayout.AddRow(myDrawable);
mainLayout.AddRow(myPanel);
mainLayout.AddRow(null);
Content = mainLayout;
For the tests, I’m using FlaUI and NUnit. The setup is also quite basic:
[OneTimeSetUp]
public void OneTimeSetUp()
{
_app = Application.Launch(@"C:\Program Files\Rhino 7\System\Rhino.exe");
Thread.Sleep(15000);
_mainWindow = Retry.WhileNull(() =>
{
var automation = new UIA3Automation();
return _app.GetMainWindow(automation);
}, TimeSpan.FromSeconds(60)).Result;
TestContext.WriteLine($"Main window found: {_mainWindow}");
_uiPanel = _mainWindow.FindFirstDescendant(cf => cf.ByName("UI_Playground"));
TestContext.WriteLine($"UI Panel found: {_uiPanel}");
}
[Test]
public void Expander_Exists()
{
var descendants = _uiPanel.FindAllDescendants();
foreach (var element in descendants)
{
TestContext.WriteLine($"Name: {element.Name}, AutomationId: {element.AutomationId}, ControlType: {element.ControlType}, Class: {element.ClassName}, Property: {element.BoundingRectangle}");
}
}
Which finds the button without issues but completely ignores the Panel and the Drawable:
Name: RhinoReorderTabCtrl_v1:9568, AutomationId: 6625, ControlType: Pane, Class: RhinoTabCtrlWindowClass, Property: {X=1464,Y=226,Width=456,Height=763}
Name: , AutomationId: 7475054, ControlType: Pane, Class: WindowsForms10.Window.8.app.0.20f9772_r42_ad1, Property: {X=1465,Y=248,Width=454,Height=739}
Name: , AutomationId: , ControlType: Pane, Class: Pane, Property: {X=1465,Y=248,Width=454,Height=739}
Name: MyButton, AutomationId: , ControlType: Button, Class: Button, Property: {X=1475,Y=258,Width=434,Height=23}
Name: , AutomationId: , ControlType: Image, Class: Image, Property: {X=0,Y=0,Width=0,Height=0}
Name: MyButton, AutomationId: , ControlType: Text, Class: Text, Property: {X=1666,Y=262,Width=53,Height=15}
Name: MyButton, AutomationId: , ControlType: Text, Class: TextBlock, Property: {X=1666,Y=262,Width=53,Height=15}
Visually, all looks good:
[EDIT]
FlaUInspect’s treeview confirms that the only recognized control is the Button: