// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; using System.Windows.Threading; namespace Core.Common.TestUtil { /// /// Used by WindowsFormsTestHelper and WpfTestHelper /// /// TODO: invert it - use GuiTestHelper as entry point in tests. /// public class GuiTestHelper { private static GuiTestHelper instance; private static Form synchronizationForm; private static Exception exception; private static bool unhandledThreadExceptionOccured; private static bool appDomainExceptionOccured; static GuiTestHelper() { Control.CheckForIllegalCrossThreadCalls = true; Application.EnableVisualStyles(); InitializeSynchronizatonObject(); Dispatcher.CurrentDispatcher.UnhandledException += CurrentDispatcher_UnhandledException; AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException; Application.ThreadException += Application_ThreadException; } public static GuiTestHelper Instance { get { if (instance == null) { instance = new GuiTestHelper(); } return instance; } } /// /// Checks build_number environment variable to determine whether we run on the build server. /// public static bool IsBuildServer { get { return File.Exists("C:\\build.server") || File.Exists("D:\\build.server") || File.Exists("/tmp/build-server") || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BUILD_NUMBER")); } } public static Exception Exception { get { return exception; } } public static void RethrowUnhandledException() { if (exception == null) { return; } if (unhandledThreadExceptionOccured) { throw new UnhandledException("Unhandled thread exception: " + exception.Message, exception, exception.StackTrace); } if (appDomainExceptionOccured) { throw new UnhandledException("Unhandled app domain exception: " + exception.Message, exception, exception.StackTrace); } } public static void Initialize() { exception = null; unhandledThreadExceptionOccured = false; appDomainExceptionOccured = false; } private static void CurrentDispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { unhandledThreadExceptionOccured = true; exception = e.Exception; RethrowUnhandledException(); } private static void InitializeSynchronizatonObject() { if (synchronizationForm == null) { synchronizationForm = new Form { ShowInTaskbar = false, WindowState = FormWindowState.Minimized, FormBorderStyle = FormBorderStyle.None }; synchronizationForm.Load += (sender, args) => synchronizationForm.Size = new Size(0, 0); var handle = synchronizationForm.Handle; //force get handle synchronizationForm.Show(); } } private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { appDomainExceptionOccured = true; exception = e.ExceptionObject as Exception; RethrowUnhandledException(); } private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { unhandledThreadExceptionOccured = true; exception = e.Exception; RethrowUnhandledException(); } /// /// Defines unhandled exception which provides stack trace of inner exception as its stack trace. /// [Serializable] public class UnhandledException : Exception { private readonly string stackTrace; public UnhandledException(string message, Exception innerException, string stackTrace) : base(message, innerException) { this.stackTrace = stackTrace; } public override string StackTrace { get { return stackTrace; } } } } }