This is Windows 10 UI automation testing via nunit3.ConsoleRunner
.
It is really pretty weird, but the same code that worked flawlessly before my vacation now hangs for so far up to 2 hours or more. I created my own MenuClick()
method for our tests because the standard MenuBar.MenuItem()
method frequently hung as well when navigating past 2nd level menu items. My method worked fine before my vacation, as I said.
Anyway, now, the Menu.SubMenu()
call frequently takes 2 hours or more to complete, which is unacceptable.
An additional bit of weirdness is that the test code clicks 3rd level menuitems in pairs, where they both open a Browse For Folder dialog. The first to select a source folder and the other to select a destination folder. The "hang" ONLY occurs (so far) when attempting to get the 2nd level submenu
for the second in the pair of 3rd level menuitem clicks.
To get around this currently, I'm spawning a new thread that invokes menu = menuBar.MenuItem(). In the main thread, I wait for menu to be non-null or for timeout to occur before proceeding with a 500 ms sleep between checks. That at least allows me to retry. However, it is appearing that, when this condition occurs, the rest of the menu operations in the entire application under test are hung, so I'm unable to retry. Seems like a bug in the TestStack.White menu handling area.
public static void GetSubMenu(object obj)
{
string[] menuNames = obj as string[];
menu = menuBar.MenuItem(menuNames);
}
private static MenuBar menuBar = null;
private static Menu menu = null;
public static int ClickMenu(MenuBar mainMenu, params string[] menuItems)
{
menuBar = mainMenu;
bool bDone = false;
menu = null;
System.Threading.Thread t = new System.Threading.Thread(GetSubMenu);
t.Start(menuItems);
System.Threading.Thread.Sleep(500);
DateTime timeOut = DateTime.Now + TimeSpan.FromSeconds(10);
while (menu == null && DateTime.Now < timeOut)
{
System.Threading.Thread.Sleep(500);
}
if (menu != null)
{
menu.Click();
bDone = true;
log.Info($"ClickMenu success");
}
t.Abort();
return bDone ? 1 : 2;
}
OK, I've determined that the TestStack.White
menu operations are susceptible to system busy state, where the thread that is trying to perform the operations doesn't get enough time slices to work, so can take a VERY, VERY long time.
Setting the worker thread priority to ThreadPriority.Highest
is key in how I implemented my test suite ClickMenu()
method as follows:
public static class Util
{
static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static MenuBar menuBar = null;
public static void MenuItem(object obj)
{
string[] path = obj as string[];
menuBar.MenuItem(path).Click();
}
public static void ClickMenu(MenuBar mainMenu, params string[] menuItems)
{
menuBar = mainMenu;
System.Threading.Thread t = new System.Threading.Thread(MenuItem);
t.Priority = System.Threading.ThreadPriority.Highest;
t.Start(menuItems);
DateTime startTime = DateTime.Now;
while (t.IsAlive)
{
System.Threading.Thread.Sleep(100);
}
DateTime endTime = DateTime.Now;
TimeSpan duration = endTime - startTime;
if (duration.Seconds > 60)
{
log.Info($"Menu Operation duration = {duration.Seconds} sec");
}
}
}