/// <summary> /// Launches the Application code - This is equivalent to the Main Method. /// </summary> static private void StartAppThread(object threadArgument) { ApplicationDriver driver = (ApplicationDriver)threadArgument; Dispatcher.CurrentDispatcher.Invoke( DispatcherPriority.ApplicationIdle, (ThreadStart) delegate { Application app = (Application)Activator.CreateInstance(driver.applicationType); // Stock VS built WPF applications have an initializeComponent step which is performed as part of the Main method. MethodInfo methodInfo = driver.applicationType.GetMethod("InitializeComponent"); if (methodInfo != null) { methodInfo.Invoke(app, null); } // Note: This is non-default step happens before Run. It is needed because the resourceAssembly we are testing is in the external WPF App bits. Application.ResourceAssembly = driver.applicationType.Assembly; app.Activated += (s, e) => { Dispatcher.CurrentDispatcher.Invoke( DispatcherPriority.ApplicationIdle, (ThreadStart) delegate { driver.dispatcherIdle.Set(); MonitorDispatcherReadiness(driver, TimeSpan.FromMilliseconds(100), DispatcherPriority.ApplicationIdle); }); }; app.Run(); }); }
/// <summary> /// Uses a timer to signal every interval over the EventWaitHandle when the Dispatcher is Idle /// </summary> /// <param name="evt">The EventWaitHandle to signal out with</param> /// <param name="interval">Time spent between polling</param> /// <param name="priority">Priority of Dispatcher to Test against</param> static private void MonitorDispatcherReadiness(ApplicationDriver driver, TimeSpan interval, DispatcherPriority priority) { DispatcherTimer timer = new DispatcherTimer(priority); timer.Interval = interval; // With each tick, we signal the idleness of the dispatcher on UI thread timer.Tick += (sender, args) => { driver.dispatcherIdle.Set(); }; timer.Start(); }
public void VerifyWindowAppearance() { ApplicationDriver driver = new ApplicationDriver(typeof(SampleApp.App)); driver.WaitForIdleUi(); AutomationElement window = AutomationUtilities.FindElementsById(AutomationElement.RootElement, "sampleAppWindow")[0]; AutomationElement styleBox = AutomationUtilities.FindElementsById(window, "styleBox")[0]; AutomationElement captureRegion = AutomationUtilities.FindElementsById(window, "captureContainer")[0]; AutomationHelpers.MoveToAndClick(styleBox); driver.WaitForIdleUi(); try { // Capture the actual pixels from the bounds of the screen rectangle Snapshot actual = Snapshot.FromRectangle(AutomationHelpers.GetElementSize(captureRegion)); LogFile(actual, "Actual.png"); // Load the reference/master data from a previously saved file Snapshot master = Snapshot.FromFile(Path.Combine(TestContext.TestDeploymentDir, "Master0.png")); LogFile(master, "Master.png"); // Log the outcome of the test, only on failure to save disk space. // For test stability in scenarios of varying window styles, consider: // -cropping the capture region to eliminate the border rectangle // -Testing on a well controlled test environment if (CompareImages(actual, master) == VerificationResult.Fail) { Assert.Fail("Initial State test failed. Actual should look like Master image. Refer to logged images under:" + TestContext.TestLogsDir); } } finally { AutomationHelpers.CloseWindow(window); driver.Join(); } }