mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-23 20:36:33 +01:00
Enforce failure if MWWaitFor times out without a message, ortherwise failures
are swallowed. Use optional parameters instead of method overloads. Some other modernisations. Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
This commit is contained in:
parent
1bf47e47df
commit
58b65f8a8a
@ -121,33 +121,24 @@ namespace XenAdmin.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first window that has the specified window text.
|
||||
/// </summary>
|
||||
/// <param name="text">The text that the window must have.</param>
|
||||
/// <returns>The first window that has the specified window text.</returns>
|
||||
public static Win32Window GetWindowWithText(string text)
|
||||
{
|
||||
return GetWindowWithText(text, w => true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first window that has the specified window text and matches the specified Predicate.
|
||||
/// </summary>
|
||||
/// <param name="text">The text that the window must have.</param>
|
||||
/// <param name="match">The Predicate that the window must match.</param>
|
||||
/// <returns>The first window that has the specified window text and matches the specified Predicate.</returns>
|
||||
public static Win32Window GetWindowWithText(string text, Predicate<Win32Window> match)
|
||||
public static Win32Window GetWindowWithText(string text, Predicate<Win32Window> match = null)
|
||||
{
|
||||
Util.ThrowIfParameterNull(match, "match");
|
||||
if (match == null)
|
||||
match = w => true;
|
||||
|
||||
Thread.Sleep(100);
|
||||
foreach (Win32Window window in TopLevelWindows)
|
||||
{
|
||||
if (window.Text == text && match(window))
|
||||
{
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -88,68 +88,59 @@ namespace XenAdminTests
|
||||
|
||||
/// <summary>
|
||||
/// Waits for the specified action to return true. The action is run on the main program thread.
|
||||
/// The action is attempted 300 times, with a 100ms wait between tries. If the action doesn't
|
||||
/// succeed after being retried then the calling test is failed with the specified message.
|
||||
/// If assert message is null, then the test won't be failed.
|
||||
/// The action is attempted 300 times, with a 100ms wait between tries.
|
||||
/// If the action has not succeeeded after the retires, the calling test fails with the specified message.
|
||||
/// </summary>
|
||||
/// <param name="action">The action.</param>
|
||||
/// <param name="assertMessage">The assert message.</param>
|
||||
/// <returns>A value indicating whether the action was successful.</returns>
|
||||
protected bool MWWaitFor(Func<bool> action, string assertMessage)
|
||||
protected bool MWWaitFor(Func<bool> action, string assertMessage = null)
|
||||
{
|
||||
bool success = false;
|
||||
for (int i = 0; i < 500 && !success; i++)
|
||||
{
|
||||
success = MW<bool>(action);
|
||||
if (!success)
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
success = MW(action);
|
||||
if (success)
|
||||
break;
|
||||
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
if (assertMessage != null && !success)
|
||||
{
|
||||
Assert.Fail(assertMessage);
|
||||
}
|
||||
if (!success)
|
||||
Assert.Fail(string.IsNullOrEmpty(assertMessage) ? "Waited unsuccessfully" : assertMessage);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for the specified action to return true. The action is run on the calling thread.
|
||||
/// The action is attempted 300 times, with a 100ms wait between tries. If the action doesn't
|
||||
/// succeed after being retried then the calling test is failed with the specified message.
|
||||
/// If assert message is null, then the test won't be failed.
|
||||
/// The action is attempted 300 times, with a 100ms wait between tries.
|
||||
/// If the action has not succeeded after the retries, the calling test fails with the specified message.
|
||||
/// </summary>
|
||||
/// <param name="action">The action.</param>
|
||||
/// <param name="assertMessage">The assert message.</param>
|
||||
/// <returns>A value indicating whether the action was successful.</returns>
|
||||
protected bool WaitFor(Func<bool> action, string assertMessage)
|
||||
protected void WaitFor(Func<bool> action, string assertMessage = null)
|
||||
{
|
||||
bool success = false;
|
||||
for (int i = 0; i < 300 && !success; i++)
|
||||
for (int i = 0; i < 300; i++)
|
||||
{
|
||||
success = action();
|
||||
if (!success)
|
||||
{
|
||||
if (success)
|
||||
break;
|
||||
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
if (!success)
|
||||
Assert.Fail(string.IsNullOrEmpty(assertMessage) ? "Waited unsuccessfully" : assertMessage);
|
||||
}
|
||||
|
||||
if (assertMessage != null && !success)
|
||||
internal Win32Window WaitForWindowToAppear(string windowText, Predicate<Win32Window> match = null)
|
||||
{
|
||||
Assert.Fail(assertMessage);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
if (match == null)
|
||||
match = w => true;
|
||||
|
||||
internal Win32Window WaitForWindowToAppear(string windowText)
|
||||
{
|
||||
return WaitForWindowToAppear(windowText, w => true);
|
||||
}
|
||||
|
||||
internal Win32Window WaitForWindowToAppear(string windowText, Predicate<Win32Window> match)
|
||||
{
|
||||
Win32Window window = null;
|
||||
Func<bool> func = delegate
|
||||
{
|
||||
@ -157,30 +148,10 @@ namespace XenAdminTests
|
||||
return window != null;
|
||||
};
|
||||
|
||||
WaitFor(func, "Window with text " + windowText + " didn't appear.");
|
||||
WaitFor(func, $"Window with text {windowText} didn't appear.");
|
||||
return window;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for the specified action to return true. The action is run on the main program thread.
|
||||
/// The action is attempted 200 times, with a 100ms wait between tries.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether the action was successful.</returns>
|
||||
protected bool MWWaitFor(Func<bool> action)
|
||||
{
|
||||
return MWWaitFor(action, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Waits for the specified action to return true. The action is run on the calling thread.
|
||||
/// The action is attempted 200 times, with a 100ms wait between tries.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether the action was successful.</returns>
|
||||
protected bool WaitFor(Func<bool> action)
|
||||
{
|
||||
return WaitFor(action, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="Application.DoEvents()"/> doesn't seems to work from the test framework. This is a replacement.
|
||||
/// </summary>
|
||||
@ -507,7 +478,7 @@ namespace XenAdminTests
|
||||
});
|
||||
|
||||
MW(openDialog);
|
||||
MWWaitFor(() => closed, "Dialog \"" + windowText + "\" was not closed.");
|
||||
MWWaitFor(() => closed, $"Dialog {windowText} was not closed.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -29,16 +29,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using XenAdmin;
|
||||
using System.Windows.Forms;
|
||||
using XenAdmin.Controls;
|
||||
using XenAdmin.Controls.MainWindowControls;
|
||||
using XenAdmin.Controls.XenSearch;
|
||||
using XenAdmin.Plugins;
|
||||
using XenAdmin.Commands;
|
||||
|
||||
|
||||
namespace XenAdminTests
|
||||
{
|
||||
@ -49,193 +44,48 @@ namespace XenAdminTests
|
||||
{
|
||||
}
|
||||
|
||||
public ToolStripMenuItem ToolsMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("toolsToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem ToolsMenu => GetField<ToolStripMenuItem>("toolsToolStripMenuItem");
|
||||
|
||||
public ToolsMenuWrapper ToolsMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ToolsMenuWrapper(Item);
|
||||
}
|
||||
}
|
||||
public ToolsMenuWrapper ToolsMenuItems => new ToolsMenuWrapper(Item);
|
||||
|
||||
public ToolStripMenuItem WindowMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("windowToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem HelpMenu => GetField<ToolStripMenuItem>("helpToolStripMenuItem");
|
||||
|
||||
public ToolStripMenuItem HelpMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("helpToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem ViewMenu => GetField<ToolStripMenuItem>("viewToolStripMenuItem");
|
||||
|
||||
public ToolStripMenuItem ViewMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("viewToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem FileMenu => GetField<ToolStripMenuItem>("fileToolStripMenuItem");
|
||||
|
||||
public ToolStripMenuItem PoolMenu => GetField<ToolStripMenuItem>("poolToolStripMenuItem");
|
||||
|
||||
public ToolStripMenuItem FileMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("fileToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem VMMenu => GetField<ToolStripMenuItem>("VMToolStripMenuItem");
|
||||
|
||||
public ToolStripMenuItem PoolMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("poolToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem TemplatesMenu => GetField<ToolStripMenuItem>("templatesToolStripMenuItem");
|
||||
|
||||
public ToolStripMenuItem VMMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("VMToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripEx MainToolStrip => GetField<ToolStripEx>("ToolStrip");
|
||||
|
||||
public ToolStripMenuItem TemplatesMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("templatesToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public MainToolBarWrapper MainToolStripItems => new MainToolBarWrapper(Item);
|
||||
|
||||
public ToolStripEx MainToolStrip
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripEx>("ToolStrip");
|
||||
}
|
||||
}
|
||||
public PluginManager PluginManager => GetField<PluginManager>("pluginManager");
|
||||
|
||||
public MainToolBarWrapper MainToolStripItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return new MainToolBarWrapper(Item);
|
||||
}
|
||||
}
|
||||
public FlickerFreeTreeView TreeView => TestUtils.GetFlickerFreeTreeView(Item, "navigationPane.navigationView.treeView");
|
||||
|
||||
public PluginManager PluginManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<PluginManager>("pluginManager");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem StorageMenu => Item.StorageToolStripMenuItem;
|
||||
|
||||
public FlickerFreeTreeView TreeView
|
||||
{
|
||||
get { return TestUtils.GetFlickerFreeTreeView(Item, "navigationPane.navigationView.treeView"); } }
|
||||
public StorageMenuWrapper StorageMenuItems => new StorageMenuWrapper(Item);
|
||||
|
||||
public CommandToolStripMenuItem AddHostToolStripMenuItemInPoolMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<CommandToolStripMenuItem>("addServerToolStripMenuItem");
|
||||
}
|
||||
}
|
||||
public ToolStripMenuItem HostMenu => GetField<ToolStripMenuItem>("HostMenuItem");
|
||||
|
||||
public ToolStripMenuItem StorageMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return Item.StorageToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
public VMMenuWrapper VMMenuItems => new VMMenuWrapper(Item);
|
||||
|
||||
public StorageMenuWrapper StorageMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return new StorageMenuWrapper(Item);
|
||||
}
|
||||
}
|
||||
public ViewMenuWrapper ViewMenuItems => new ViewMenuWrapper(Item);
|
||||
|
||||
public ToolStripMenuItem HostMenu
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<ToolStripMenuItem>("HostMenuItem");
|
||||
}
|
||||
}
|
||||
public TabControl TheTabControl => Item.TheTabControl;
|
||||
|
||||
public HostMenuWrapper HostMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return new HostMenuWrapper(Item);
|
||||
}
|
||||
}
|
||||
public MenuStripEx MainMenuBar => GetField<MenuStripEx>("MainMenuBar");
|
||||
|
||||
public VMMenuWrapper VMMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return new VMMenuWrapper(Item);
|
||||
}
|
||||
}
|
||||
public NetworkTabPageWrapper NetworkPage => new NetworkTabPageWrapper(Item.NetworkPage);
|
||||
|
||||
public ViewMenuWrapper ViewMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ViewMenuWrapper(Item);
|
||||
}
|
||||
}
|
||||
public TabPage TabPageNetwork => GetField<TabPage>("TabPageNetwork");
|
||||
|
||||
public TabControl TheTabControl
|
||||
{
|
||||
get
|
||||
{
|
||||
return Item.TheTabControl;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuStripEx MainMenuBar
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<XenAdmin.Controls.MenuStripEx>("MainMenuBar");
|
||||
}
|
||||
}
|
||||
|
||||
public NetworkTabPageWrapper NetworkPage
|
||||
{
|
||||
get
|
||||
{
|
||||
return new NetworkTabPageWrapper(Item.NetworkPage);
|
||||
}
|
||||
}
|
||||
|
||||
public TabPage TabPageNetwork
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetField<TabPage>("TabPageNetwork");
|
||||
}
|
||||
}
|
||||
public Form[] OwnedForms => Item.OwnedForms;
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,10 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using NUnit.Framework;
|
||||
using XenAdmin;
|
||||
using XenAdmin.Core;
|
||||
|
||||
namespace XenAdminTests
|
||||
{
|
||||
@ -50,44 +48,25 @@ namespace XenAdminTests
|
||||
{
|
||||
private readonly TClass _item;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TestWrapper<TClass>"/> class.
|
||||
/// </summary>
|
||||
/// <param name="item">The class that is to be wrapped.</param>
|
||||
public TestWrapper(TClass item)
|
||||
protected TestWrapper(TClass item)
|
||||
{
|
||||
Util.ThrowIfParameterNull(item, "item");
|
||||
_item = item;
|
||||
}
|
||||
|
||||
private static TClass GetControlFromWindow(IWin32Window window)
|
||||
{
|
||||
Control control = Control.FromHandle(window.Handle);
|
||||
|
||||
if (!(control is TClass))
|
||||
{
|
||||
throw new ArgumentException("window is not a " + typeof(TClass).Name, "window");
|
||||
}
|
||||
|
||||
return control as TClass;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="TestWrapper<TClass>"/> class.
|
||||
/// </summary>
|
||||
/// <param name="window">The window.</param>
|
||||
public TestWrapper(IWin32Window window)
|
||||
protected TestWrapper(IWin32Window window)
|
||||
: this(GetControlFromWindow(window))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TestWrapper<TClass>"/> class.
|
||||
/// </summary>
|
||||
/// <param name="windowText">The window text of the window being wrapped.</param>
|
||||
public TestWrapper(string windowText)
|
||||
: this(Win32Window.GetWindowWithText(windowText, w => Control.FromHandle(w.Handle) is TClass))
|
||||
private static TClass GetControlFromWindow(IWin32Window window)
|
||||
{
|
||||
var control = Control.FromHandle(window.Handle) as TClass;
|
||||
|
||||
if (control == null)
|
||||
throw new ArgumentException($"window is not a {typeof(TClass).Name} window");
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -112,10 +91,10 @@ namespace XenAdminTests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the private field from the wrapped classes *base* class of the specified name.
|
||||
/// Gets the value of a given private field from the wrapped class's *base* class
|
||||
/// </summary>
|
||||
/// <typeparam name="TField">The type of the field.</typeparam>
|
||||
/// <param name="name">The name of the private field.</param>
|
||||
/// <param name="name">The name of the field.</param>
|
||||
/// <returns>The value of the private field from the base class of the wrapped class of the specified name.</returns>
|
||||
protected TField GetBaseClassField<TField>(string name)
|
||||
{
|
||||
@ -125,14 +104,13 @@ namespace XenAdminTests
|
||||
{
|
||||
Type baseType = _item.GetType().BaseType;
|
||||
|
||||
if(baseType == null)
|
||||
throw new NoNullAllowedException("Base class type was null, check the class has a base class");
|
||||
Assert.NotNull(baseType, $"{name} is a field of a class that has no base class");
|
||||
|
||||
return (TField)baseType.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_item);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Assert.Fail(string.Format("Field {0} of {1} throws {2}.", name, typeof(TClass).Name, e.GetType().Name));
|
||||
Assert.Fail($"Field {name} of {typeof(TClass).Name} throws {e.GetType().Name}.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -118,36 +118,20 @@ namespace XenAdminTests.MiscTests
|
||||
[Test]
|
||||
public void TestMultipleUrisWithNoneValid()
|
||||
{
|
||||
Uri uri1 = new Uri("http://fgdfffgd.dfgdfgd.dfg");
|
||||
Uri uri2 = new Uri("http://fgdfgd.dfgdfgd.dfg");
|
||||
Uri navCancelUri = new Uri("res://ieframe.dll/navcancl.htm#http://fgdfgd.dfgdfgd.dfg/");
|
||||
Uri curUri = null;
|
||||
bool navigating = false;
|
||||
bool navigated = false;
|
||||
bool navError = false;
|
||||
|
||||
_wb.Navigating += (s, e) =>
|
||||
{
|
||||
if (e.Url != navCancelUri)
|
||||
{
|
||||
Assert.IsFalse(navigating);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(navigating);
|
||||
}
|
||||
if (e.Url == curUri)
|
||||
navigating = true;
|
||||
};
|
||||
|
||||
_wb.Navigated += (s, e) =>
|
||||
{
|
||||
if (e.Url != navCancelUri)
|
||||
{
|
||||
Assert.IsFalse(navigated);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsTrue(navigated);
|
||||
}
|
||||
if (e.Url == curUri)
|
||||
navigated = true;
|
||||
};
|
||||
|
||||
@ -157,10 +141,20 @@ namespace XenAdminTests.MiscTests
|
||||
navError = true;
|
||||
};
|
||||
|
||||
var uris = new[] { uri1, uri2 };
|
||||
//Use non-existing URLs with existing rather than completely fictional
|
||||
//domains, otherwise the NavigationError even is not fired
|
||||
|
||||
var uris = new[]
|
||||
{
|
||||
new Uri("http://127.0.0.1/blah"),
|
||||
new Uri("http://127.0.0.1/blahblah")
|
||||
};
|
||||
|
||||
foreach (var uri in uris)
|
||||
{
|
||||
var curUri = uri;
|
||||
curUri = uri;
|
||||
|
||||
navigated = navigated = navError = false;
|
||||
MW(() => _wb.Navigate(curUri));
|
||||
MWWaitFor(() => navigating && navigated && navError, "Navigation didn't take place.");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user