2015-05-07 19:57:33 -07:00
|
|
|
|
/*
|
|
|
|
|
|
Copyright (c) 2014, Lars Brubaker
|
|
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
|
|
|
|
list of conditions and the following disclaimer.
|
|
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
|
|
this list of conditions and the following disclaimer in the documentation
|
|
|
|
|
|
and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
|
|
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
|
|
|
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
|
|
The views and conclusions contained in the software and documentation are those
|
|
|
|
|
|
of the authors and should not be interpreted as representing official policies,
|
|
|
|
|
|
either expressed or implied, of the FreeBSD Project.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2016-09-20 09:39:57 -07:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reflection;
|
2016-11-05 10:56:52 -07:00
|
|
|
|
using System.Threading;
|
2016-10-25 06:17:37 -07:00
|
|
|
|
using System.Threading.Tasks;
|
2016-09-20 09:39:57 -07:00
|
|
|
|
using MatterHackers.Agg;
|
2015-05-07 19:57:33 -07:00
|
|
|
|
using MatterHackers.Agg.Image;
|
2017-08-20 02:34:39 -07:00
|
|
|
|
using MatterHackers.Agg.Platform;
|
2015-05-26 11:59:56 -07:00
|
|
|
|
using MatterHackers.Agg.UI;
|
2015-08-18 13:01:29 -07:00
|
|
|
|
using MatterHackers.GuiAutomation;
|
2017-10-27 14:19:26 -07:00
|
|
|
|
using MatterHackers.MatterControl.CustomWidgets;
|
2015-08-25 11:56:21 -07:00
|
|
|
|
using MatterHackers.MatterControl.DataStorage;
|
2017-10-31 11:22:58 -07:00
|
|
|
|
using MatterHackers.MatterControl.PartPreviewWindow;
|
2017-06-02 21:20:56 -07:00
|
|
|
|
using MatterHackers.MatterControl.PrinterCommunication;
|
2017-12-07 14:54:41 -08:00
|
|
|
|
using MatterHackers.MatterControl.PrinterControls.PrinterConnections;
|
2017-10-14 10:53:42 -07:00
|
|
|
|
using MatterHackers.MatterControl.PrintLibrary;
|
2016-11-04 10:23:29 -07:00
|
|
|
|
using MatterHackers.MatterControl.SlicerConfiguration;
|
2017-01-10 12:24:01 -08:00
|
|
|
|
using MatterHackers.PrinterEmulator;
|
2015-10-22 18:23:22 -07:00
|
|
|
|
using Newtonsoft.Json;
|
2016-10-19 13:27:27 -07:00
|
|
|
|
using Newtonsoft.Json.Converters;
|
2015-08-22 16:14:31 -07:00
|
|
|
|
using NUnit.Framework;
|
2017-12-07 12:23:28 -08:00
|
|
|
|
using MatterHackers.MatterControl.PrinterControls.PrinterConnections;
|
2017-12-15 19:21:50 -08:00
|
|
|
|
using MatterHackers.MatterControl.PrinterCommunication.Io;
|
2015-05-07 19:57:33 -07:00
|
|
|
|
|
2016-05-11 09:13:56 -07:00
|
|
|
|
namespace MatterHackers.MatterControl.Tests.Automation
|
2015-05-07 19:57:33 -07:00
|
|
|
|
{
|
2016-05-11 09:13:56 -07:00
|
|
|
|
[TestFixture, Category("MatterControl.UI.Automation")]
|
2015-09-01 10:26:14 -07:00
|
|
|
|
public static class MatterControlUtilities
|
2015-05-07 19:57:33 -07:00
|
|
|
|
{
|
|
|
|
|
|
private static bool saveImagesForDebug = true;
|
|
|
|
|
|
|
2016-11-05 10:56:52 -07:00
|
|
|
|
private static event EventHandler unregisterEvents;
|
|
|
|
|
|
|
2015-12-22 11:34:04 -08:00
|
|
|
|
private static int testID = 0;
|
|
|
|
|
|
|
|
|
|
|
|
private static string runName = DateTime.Now.ToString("yyyy-MM-ddTHH-mm-ss");
|
|
|
|
|
|
|
2017-12-08 19:02:41 -08:00
|
|
|
|
public static string PathToDownloadsSubFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "-Temporary");
|
2017-12-16 19:09:25 -08:00
|
|
|
|
|
|
|
|
|
|
private static SystemWindow rootSystemWindow;
|
|
|
|
|
|
|
2016-12-01 13:25:17 -08:00
|
|
|
|
public static void RemoveAllFromQueue(this AutomationRunner testRunner)
|
2015-08-18 13:01:29 -07:00
|
|
|
|
{
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Queue... Menu");
|
2017-02-01 10:12:31 -08:00
|
|
|
|
testRunner.Delay(1);
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName(" Remove All Menu Item");
|
2015-08-20 10:24:28 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-01-13 17:02:41 -08:00
|
|
|
|
public static void CreateDownloadsSubFolder()
|
2017-12-08 19:18:28 -08:00
|
|
|
|
{
|
|
|
|
|
|
if (Directory.Exists(PathToDownloadsSubFolder))
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (string filePath in Directory.GetFiles(PathToDownloadsSubFolder))
|
|
|
|
|
|
{
|
|
|
|
|
|
File.Delete(filePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2017-12-08 19:19:22 -08:00
|
|
|
|
{
|
|
|
|
|
|
Directory.CreateDirectory(PathToDownloadsSubFolder);
|
|
|
|
|
|
}
|
2017-12-08 19:18:28 -08:00
|
|
|
|
}
|
2017-12-08 19:02:41 -08:00
|
|
|
|
|
2016-09-30 16:03:57 -07:00
|
|
|
|
public static void DeleteDownloadsSubFolder()
|
2016-01-13 17:02:41 -08:00
|
|
|
|
{
|
2016-09-30 16:03:57 -07:00
|
|
|
|
Directory.Delete(PathToDownloadsSubFolder, true);
|
2016-01-13 17:02:41 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-19 09:38:20 -07:00
|
|
|
|
public static void SignOut(AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("User Options Menu");
|
|
|
|
|
|
testRunner.ClickByName("Sign Out Menu Item");
|
2017-02-01 10:12:31 -08:00
|
|
|
|
testRunner.Delay(.5);
|
2016-09-23 14:16:39 -07:00
|
|
|
|
|
2016-11-05 10:56:52 -07:00
|
|
|
|
// Rather than waiting a fixed amount of time, we wait for the ReloadAll to complete before returning
|
|
|
|
|
|
testRunner.WaitForReloadAll(() => testRunner.ClickByName("Yes Button"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void WaitForReloadAll(this AutomationRunner testRunner, Action reloadAllAction)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Wire up a block and release mechanism to wait until the sign in process has completed
|
|
|
|
|
|
AutoResetEvent resetEvent = new AutoResetEvent(false);
|
|
|
|
|
|
ApplicationController.Instance.DoneReloadingAll.RegisterEvent((s, e) => resetEvent.Set(), ref unregisterEvents);
|
|
|
|
|
|
|
|
|
|
|
|
// Start the procedure that begins a ReloadAll event in MatterControl
|
|
|
|
|
|
reloadAllAction();
|
|
|
|
|
|
|
2016-12-06 18:52:25 -08:00
|
|
|
|
// Wait up to 10 seconds for the DoneReloadingAll event
|
|
|
|
|
|
resetEvent.WaitOne(10 * 1000);
|
2016-11-05 10:56:52 -07:00
|
|
|
|
|
|
|
|
|
|
// Remove our DoneReloadingAll listener
|
|
|
|
|
|
unregisterEvents(null, null);
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for any post DoneReloadingAll code to finish up and return
|
2017-02-01 10:12:31 -08:00
|
|
|
|
testRunner.Delay(.2);
|
2016-09-19 09:38:20 -07:00
|
|
|
|
}
|
2016-01-13 17:02:41 -08:00
|
|
|
|
|
2015-12-31 12:57:00 -08:00
|
|
|
|
public static string PathToExportGcodeFolder
|
|
|
|
|
|
{
|
2016-09-22 08:52:15 -07:00
|
|
|
|
get { return TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "ExportedGcode", runName); }
|
2015-12-31 12:57:00 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-01-13 17:02:41 -08:00
|
|
|
|
public static string GetTestItemPath(string queueItemToLoad)
|
2015-10-23 09:57:26 -07:00
|
|
|
|
{
|
2016-09-22 08:52:15 -07:00
|
|
|
|
return TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "QueueItems", queueItemToLoad);
|
2015-10-23 09:57:26 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-14 21:59:41 -08:00
|
|
|
|
public static void CloseMatterControl(this AutomationRunner testRunner)
|
2015-08-20 10:24:28 -07:00
|
|
|
|
{
|
2017-12-16 19:09:25 -08:00
|
|
|
|
rootSystemWindow?.Close();
|
2015-08-18 13:01:29 -07:00
|
|
|
|
}
|
2015-08-20 18:42:34 -07:00
|
|
|
|
|
2016-07-29 16:44:00 -07:00
|
|
|
|
public enum PrepAction
|
|
|
|
|
|
{
|
2016-08-29 17:13:45 -07:00
|
|
|
|
CloseSignInAndPrinterSelect,
|
2016-07-29 16:44:00 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
2017-03-15 16:17:06 -07:00
|
|
|
|
public static void Select3DPart(this AutomationRunner testRunner, string partNameToSelect)
|
|
|
|
|
|
{
|
2017-12-06 17:23:21 -08:00
|
|
|
|
if (testRunner.NameExists("3D View Edit", .2))
|
2017-03-15 16:17:06 -07:00
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("3D View Edit");
|
|
|
|
|
|
}
|
2017-07-11 08:10:57 -07:00
|
|
|
|
testRunner.DragDropByName("InteractionLayer", "InteractionLayer", offsetDrop: new Agg.Point2D(10, 15), mouseButtons: MouseButtons.Right);
|
2017-03-15 16:17:06 -07:00
|
|
|
|
|
|
|
|
|
|
testRunner.Delay(1);
|
|
|
|
|
|
testRunner.ClickByName(partNameToSelect);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-26 08:35:51 -07:00
|
|
|
|
public static void CloseSignInAndPrinterSelect(this AutomationRunner testRunner, PrepAction preAction = PrepAction.CloseSignInAndPrinterSelect)
|
2016-07-29 16:44:00 -07:00
|
|
|
|
{
|
2017-11-15 16:00:07 -08:00
|
|
|
|
// NOTE: Tests fail to detect and close this Window when delay is ~.5
|
|
|
|
|
|
//
|
2016-10-26 08:35:51 -07:00
|
|
|
|
// Non-MCCentral builds won't have the plugin. Reduce the wait time for these cases
|
2017-11-15 16:00:07 -08:00
|
|
|
|
if (testRunner.WaitForName("Connection Wizard Skip Sign In Button", 1))
|
2016-07-29 16:44:00 -07:00
|
|
|
|
{
|
2016-10-26 08:35:51 -07:00
|
|
|
|
testRunner.ClickByName("Connection Wizard Skip Sign In Button");
|
2016-07-29 16:44:00 -07:00
|
|
|
|
}
|
2016-10-26 08:35:51 -07:00
|
|
|
|
|
2016-12-01 13:25:17 -08:00
|
|
|
|
if (testRunner.WaitForName("Cancel Wizard Button", 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Cancel Wizard Button");
|
|
|
|
|
|
}
|
2016-07-29 16:44:00 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-21 16:29:00 -07:00
|
|
|
|
public static void ChangeToQueueContainer(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.NavigateToFolder("Print Queue Row Item Collection");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-06 17:23:21 -08:00
|
|
|
|
public class PrintEmulatorProcess : Process
|
2016-10-26 07:27:16 -07:00
|
|
|
|
{
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
|
{
|
2016-12-07 13:21:53 -08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
this.Kill();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch { }
|
|
|
|
|
|
|
2016-10-26 07:27:16 -07:00
|
|
|
|
base.Dispose(disposing);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-02 19:57:15 -07:00
|
|
|
|
public static Emulator LaunchAndConnectToPrinterEmulator(this AutomationRunner testRunner, string make = "Airwolf 3D", string model = "HD", bool runSlow = false)
|
2016-09-14 15:50:24 -07:00
|
|
|
|
{
|
2016-09-20 09:39:57 -07:00
|
|
|
|
// Load the TestEnv config
|
|
|
|
|
|
var config = TestAutomationConfig.Load();
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
2017-12-15 19:21:50 -08:00
|
|
|
|
// Override the heat up time
|
2017-12-15 18:19:36 -08:00
|
|
|
|
Emulator.DefaultHeatUpTime = config.HeatupTime;
|
2017-12-15 19:21:50 -08:00
|
|
|
|
|
|
|
|
|
|
// Override the temp stablization time
|
|
|
|
|
|
WaitForTempStream.WaitAfterReachTempTime = config.TempStabilizationTime;
|
|
|
|
|
|
|
2016-09-20 09:39:57 -07:00
|
|
|
|
// Create the printer
|
2017-06-04 09:01:56 -07:00
|
|
|
|
testRunner.AddAndSelectPrinter(make, model);
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
2017-07-01 18:25:53 -07:00
|
|
|
|
// Force the configured printer to use the emulator driver
|
|
|
|
|
|
ActiveSliceSettings.Instance.SetValue("driver_type", "Emulator");
|
2016-09-14 15:50:24 -07:00
|
|
|
|
|
2016-09-19 14:46:47 -07:00
|
|
|
|
// edit the com port
|
2017-08-30 10:37:44 -07:00
|
|
|
|
testRunner.ClickByName("Slice Settings Sidebar");
|
|
|
|
|
|
testRunner.ClickByName("Printer Tab");
|
2017-09-22 23:28:00 -07:00
|
|
|
|
var serialPortDropDown = testRunner.GetWidgetByName("com_port Field", out _, 1);
|
2017-01-06 16:54:34 -08:00
|
|
|
|
|
2017-12-15 20:24:58 -08:00
|
|
|
|
testRunner.WaitFor(() => serialPortDropDown.Enabled); // Wait until the serialPortDropDown is ready to click it. Ensures the printer is loaded.
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
2017-09-22 23:28:00 -07:00
|
|
|
|
testRunner.ClickByName("com_port Field");
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
2017-07-01 18:25:53 -07:00
|
|
|
|
testRunner.ClickByName("Emulator Menu Item");
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
|
|
|
|
|
// connect to the created printer
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Connect to printer button");
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
2017-06-14 14:02:29 -07:00
|
|
|
|
testRunner.WaitForName("Disconnect from printer button");
|
2016-09-19 14:46:47 -07:00
|
|
|
|
|
2017-07-01 18:25:53 -07:00
|
|
|
|
// Access through static instance must occur after Connect has occurred and the port has spun up
|
|
|
|
|
|
Emulator.Instance.RunSlow = runSlow;
|
|
|
|
|
|
|
|
|
|
|
|
return Emulator.Instance;
|
2017-12-06 17:23:21 -08:00
|
|
|
|
}
|
2016-09-14 15:50:24 -07:00
|
|
|
|
|
2017-02-01 10:20:50 -08:00
|
|
|
|
public static void CancelPrint(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-12-14 21:59:41 -08:00
|
|
|
|
// TODO: Improve this to more accurately find the print task row and click its Stop button
|
|
|
|
|
|
testRunner.ClickByName("Stop Task Button");
|
2017-02-01 10:20:50 -08:00
|
|
|
|
|
|
|
|
|
|
if (testRunner.WaitForName("Yes Button", 1))
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Yes Button");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-14 21:59:41 -08:00
|
|
|
|
public static void WaitForLayer(this Emulator emulator, PrinterSettings printerSettings, int layerNumber, double secondsToWait = 30)
|
|
|
|
|
|
{
|
|
|
|
|
|
var resetEvent = new AutoResetEvent(false);
|
|
|
|
|
|
|
|
|
|
|
|
var heightAtTargetLayer = printerSettings.GetValue<double>(SettingsKey.layer_height) * layerNumber;
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for emulator to hit target layer
|
|
|
|
|
|
emulator.ZPositionChanged += (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// Wait for print to start, then slow down the emulator and continue. Failing to slow down frequently causes a timing issue where the print
|
|
|
|
|
|
// finishes before we make it down to 'CloseMatterControlViaUi' and thus no prompt to close appears and the test fails when clicking 'Yes Button'
|
|
|
|
|
|
if (emulator.ZPosition >= heightAtTargetLayer)
|
|
|
|
|
|
{
|
|
|
|
|
|
resetEvent.Set();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
resetEvent.WaitOne((int) (secondsToWait * 1000));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-03-03 16:57:43 -08:00
|
|
|
|
public static bool CompareExpectedSliceSettingValueWithActualVaue(string sliceSetting, string expectedValue)
|
|
|
|
|
|
{
|
2016-09-23 13:34:57 -07:00
|
|
|
|
string fullPath = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "temp", runName, "Test0", "data", "gcode");
|
2016-03-03 16:57:43 -08:00
|
|
|
|
|
2016-11-04 10:23:29 -07:00
|
|
|
|
foreach (string iniPath in Directory.GetFiles(fullPath, "*.ini"))
|
2016-03-03 16:57:43 -08:00
|
|
|
|
{
|
2016-11-04 10:23:29 -07:00
|
|
|
|
var settings = PrinterSettingsLayer.LoadFromIni(iniPath);
|
|
|
|
|
|
|
|
|
|
|
|
string currentValue;
|
2016-03-03 16:57:43 -08:00
|
|
|
|
|
2016-11-04 10:23:29 -07:00
|
|
|
|
if (settings.TryGetValue(sliceSetting, out currentValue))
|
|
|
|
|
|
{
|
|
|
|
|
|
return currentValue.Trim() == expectedValue;
|
2016-03-03 16:57:43 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-09-08 14:20:39 -07:00
|
|
|
|
public static void DeleteSelectedPrinter(AutomationRunner testRunner)
|
|
|
|
|
|
{
|
|
|
|
|
|
// delete printer
|
2017-08-30 16:43:58 -07:00
|
|
|
|
testRunner.ClickByName("Printer Overflow Menu");
|
|
|
|
|
|
testRunner.ClickByName("Delete Printer Menu Item");
|
2016-11-05 11:12:20 -07:00
|
|
|
|
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.WaitForReloadAll(() => testRunner.ClickByName("Yes Button"));
|
2016-09-08 14:20:39 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-04 09:01:56 -07:00
|
|
|
|
public static void AddAndSelectPrinter(this AutomationRunner testRunner, string make, string model)
|
2016-01-13 10:26:17 -08:00
|
|
|
|
{
|
2017-06-04 16:16:07 -07:00
|
|
|
|
// If SelectMake is not visible and the ConnectionWizard is, click Skip
|
2017-12-07 12:23:28 -08:00
|
|
|
|
if (!testRunner.NameExists("Select Make", 0.1))
|
2017-06-04 16:16:07 -07:00
|
|
|
|
{
|
2017-09-16 13:47:19 -07:00
|
|
|
|
// Go to the new tab screen
|
|
|
|
|
|
testRunner.ClickByName("Create New");
|
|
|
|
|
|
testRunner.ClickByName("Create Printer");
|
2017-06-04 16:16:07 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Select Make");
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => testRunner.WidgetExists<PopupWidget>());
|
2016-09-26 15:59:29 -07:00
|
|
|
|
testRunner.Type(make);
|
2016-10-17 11:04:39 -07:00
|
|
|
|
testRunner.Type("{Enter}");
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => !testRunner.WidgetExists<PopupWidget>());
|
2017-12-07 12:23:28 -08:00
|
|
|
|
|
2016-01-13 10:26:17 -08:00
|
|
|
|
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Select Model");
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => testRunner.WidgetExists<PopupWidget>());
|
2016-12-12 17:33:02 -08:00
|
|
|
|
testRunner.Type(model);
|
|
|
|
|
|
testRunner.Type("{Enter}");
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => !testRunner.WidgetExists<PopupWidget>());
|
2016-08-29 17:13:45 -07:00
|
|
|
|
|
2016-11-15 15:02:34 -08:00
|
|
|
|
// An unpredictable period of time will pass between Clicking Save, everything reloading and us returning to the caller.
|
|
|
|
|
|
// Block until ReloadAll has completed then close and return to the caller, at which point hopefully everything is reloaded.
|
2017-11-30 09:44:32 -08:00
|
|
|
|
testRunner.WaitForReloadAll(() => testRunner.ClickByName("Save & Continue Button"));
|
2016-08-29 17:13:45 -07:00
|
|
|
|
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => testRunner.WidgetExists<SetupStepInstallDriver>());
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Cancel Wizard Button");
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => !testRunner.WidgetExists<SetupStepInstallDriver>());
|
2016-01-13 10:26:17 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-04 16:16:07 -07:00
|
|
|
|
public static void OpenPrintersDropdown(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-08-30 16:43:58 -07:00
|
|
|
|
testRunner.ClickByName("Create New");
|
2017-06-04 16:16:07 -07:00
|
|
|
|
testRunner.ClickByName("Printers... Menu");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void ClosePrintersDropdown(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-08-30 16:43:58 -07:00
|
|
|
|
testRunner.ClickByName("Printers... Menu");
|
2017-06-04 16:16:07 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-09-01 10:26:14 -07:00
|
|
|
|
private static void OutputImage(ImageBuffer imageToOutput, string fileName)
|
2015-05-07 19:57:33 -07:00
|
|
|
|
{
|
|
|
|
|
|
if (saveImagesForDebug)
|
|
|
|
|
|
{
|
|
|
|
|
|
ImageTgaIO.Save(imageToOutput, fileName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-09-01 10:26:14 -07:00
|
|
|
|
private static void OutputImage(GuiWidget widgetToOutput, string fileName)
|
2015-05-07 19:57:33 -07:00
|
|
|
|
{
|
|
|
|
|
|
if (saveImagesForDebug)
|
|
|
|
|
|
{
|
|
|
|
|
|
OutputImage(widgetToOutput.BackBuffer, fileName);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2015-09-01 10:26:14 -07:00
|
|
|
|
private static void OutputImages(GuiWidget control, GuiWidget test)
|
2015-05-07 19:57:33 -07:00
|
|
|
|
{
|
|
|
|
|
|
OutputImage(control, "image-control.tga");
|
|
|
|
|
|
OutputImage(test, "image-test.tga");
|
|
|
|
|
|
}
|
2015-08-25 11:56:21 -07:00
|
|
|
|
|
2015-12-22 11:34:04 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Overrides the AppData location, ensuring each test starts with a fresh MatterControl database.
|
|
|
|
|
|
/// </summary>
|
2016-09-20 09:39:57 -07:00
|
|
|
|
public static void OverrideAppDataLocation(string matterControlDirectory)
|
2015-08-25 11:56:21 -07:00
|
|
|
|
{
|
2016-09-20 14:32:22 -07:00
|
|
|
|
string tempFolderPath = Path.Combine(matterControlDirectory, "Tests", "temp", runName, $"Test{testID++}");
|
2016-09-20 09:39:57 -07:00
|
|
|
|
ApplicationDataStorage.Instance.OverrideAppDataLocation(tempFolderPath);
|
2015-08-25 11:56:21 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2015-10-22 18:23:22 -07:00
|
|
|
|
public static void AddItemsToQueue(string queueItemFolderToLoad)
|
|
|
|
|
|
{
|
2016-09-23 14:16:39 -07:00
|
|
|
|
// Default location of mcp file
|
2015-10-22 18:23:22 -07:00
|
|
|
|
string mcpPath = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "default.mcp");
|
|
|
|
|
|
|
|
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(mcpPath));
|
|
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(mcpPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
File.WriteAllText(mcpPath, JsonConvert.SerializeObject(new ManifestFile()
|
2016-09-20 14:32:22 -07:00
|
|
|
|
{
|
|
|
|
|
|
ProjectFiles = new System.Collections.Generic.List<PrintItem>()
|
|
|
|
|
|
}, Formatting.Indented));
|
2015-10-22 18:23:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var queueItemData = JsonConvert.DeserializeObject<ManifestFile>(File.ReadAllText(mcpPath));
|
|
|
|
|
|
|
|
|
|
|
|
string queueData = Path.Combine(ApplicationDataStorage.ApplicationUserDataPath, "data", "testitems");
|
|
|
|
|
|
|
2016-09-23 14:16:39 -07:00
|
|
|
|
// Create empty TestParts folder
|
2015-10-22 18:23:22 -07:00
|
|
|
|
Directory.CreateDirectory(queueData);
|
|
|
|
|
|
|
2016-09-22 08:52:15 -07:00
|
|
|
|
string queueItemsDirectory = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "Tests", "TestData", "QueueItems", queueItemFolderToLoad);
|
2015-12-22 11:34:04 -08:00
|
|
|
|
|
2016-09-22 08:52:15 -07:00
|
|
|
|
foreach (string file in Directory.GetFiles(queueItemsDirectory))
|
2015-10-22 18:23:22 -07:00
|
|
|
|
{
|
|
|
|
|
|
string newFilePath = Path.Combine(queueData, Path.GetFileName(file));
|
|
|
|
|
|
File.Copy(file, newFilePath, true);
|
|
|
|
|
|
queueItemData.ProjectFiles.Add(new PrintItem()
|
2016-09-22 08:52:15 -07:00
|
|
|
|
{
|
|
|
|
|
|
FileLocation = newFilePath,
|
|
|
|
|
|
Name = Path.GetFileNameWithoutExtension(file),
|
|
|
|
|
|
DateAdded = DateTime.Now
|
|
|
|
|
|
});
|
2015-10-22 18:23:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
File.WriteAllText(mcpPath, JsonConvert.SerializeObject(queueItemData, Formatting.Indented));
|
|
|
|
|
|
|
|
|
|
|
|
Assert.IsTrue(queueItemData != null && queueItemData.ProjectFiles.Count > 0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-12-01 13:25:17 -08:00
|
|
|
|
public static void NavigateToFolder(this AutomationRunner testRunner, string libraryRowItemName)
|
2015-09-01 16:03:29 -07:00
|
|
|
|
{
|
2017-10-14 10:53:42 -07:00
|
|
|
|
EnsureFoldersVisible(testRunner);
|
2017-05-20 17:47:36 -07:00
|
|
|
|
testRunner.DoubleClickByName(libraryRowItemName);
|
2015-09-01 16:03:29 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-14 10:53:42 -07:00
|
|
|
|
public static void EnsureFoldersVisible(this AutomationRunner testRunner)
|
2017-08-30 16:43:58 -07:00
|
|
|
|
{
|
2017-12-07 14:54:41 -08:00
|
|
|
|
var checkBox = (ExpandCheckboxButton)testRunner.GetWidgetByName("Show Folders Toggle", out _);
|
2017-08-30 16:43:58 -07:00
|
|
|
|
if (!checkBox.Checked)
|
|
|
|
|
|
{
|
2017-12-08 11:32:05 -08:00
|
|
|
|
var resetEvent = new AutoResetEvent(false);
|
|
|
|
|
|
|
|
|
|
|
|
// Wire up event listener
|
|
|
|
|
|
var listView = testRunner.GetWidgetByName("LibraryView", out _) as ListView;
|
|
|
|
|
|
EventHandler contentReloaded = (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
resetEvent.Set();
|
|
|
|
|
|
};
|
|
|
|
|
|
listView.ContentReloaded += contentReloaded;
|
|
|
|
|
|
|
|
|
|
|
|
// Start reload
|
2017-08-30 16:43:58 -07:00
|
|
|
|
testRunner.ClickByName("Show Folders Toggle");
|
2017-12-07 14:54:41 -08:00
|
|
|
|
|
2017-12-08 11:32:05 -08:00
|
|
|
|
// Wait for reload
|
|
|
|
|
|
resetEvent.WaitOne();
|
|
|
|
|
|
|
|
|
|
|
|
// Release event listener
|
|
|
|
|
|
listView.ContentReloaded -= contentReloaded;
|
|
|
|
|
|
}
|
2017-12-07 14:54:41 -08:00
|
|
|
|
|
2017-08-30 16:43:58 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-18 10:02:34 -07:00
|
|
|
|
public static void NavigateToLibraryHome(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-12-06 17:23:21 -08:00
|
|
|
|
while (!testRunner.NameExists("Local Library Row Item Collection", .5))
|
2017-06-18 10:02:34 -07:00
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Library Up Button");
|
|
|
|
|
|
testRunner.Delay(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
testRunner.Delay(.5);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-06 15:21:18 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Types the specified text into the dialog and sends {Enter} to complete the interaction
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner">The TestRunner to interact with</param>
|
|
|
|
|
|
/// <param name="textValue">The text to type</param>
|
2017-12-09 14:20:25 -08:00
|
|
|
|
public static void CompleteDialog(this AutomationRunner testRunner, string textValue, double secondsToWait = 2)
|
2017-12-06 15:21:18 -08:00
|
|
|
|
{
|
|
|
|
|
|
// AutomationDialog requires no delay
|
2017-12-06 17:23:21 -08:00
|
|
|
|
if (AggContext.FileDialogs is AutomationDialogProvider)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Wait for text widget to have focus
|
|
|
|
|
|
var widget = testRunner.GetWidgetByName("Automation Dialog TextEdit", out _, 5);
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => widget.ContainsFocus);
|
2017-12-06 17:23:21 -08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2017-12-06 15:21:18 -08:00
|
|
|
|
{
|
|
|
|
|
|
testRunner.Delay(secondsToWait);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-06 17:23:21 -08:00
|
|
|
|
testRunner.Type(textValue);
|
|
|
|
|
|
|
2017-12-06 15:21:18 -08:00
|
|
|
|
testRunner.Type("{Enter}");
|
2017-12-15 20:29:16 -08:00
|
|
|
|
testRunner.WaitForWidgetDisappear("Automation Dialog TextEdit", 5);
|
2017-12-06 15:21:18 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-27 14:19:26 -07:00
|
|
|
|
public static void AddItemToBedplate(this AutomationRunner testRunner, string containerName = "Calibration Parts Row Item Collection", string partName = "Row Item Calibration - Box.stl")
|
2017-06-02 19:40:10 -07:00
|
|
|
|
{
|
2017-11-01 13:57:45 -07:00
|
|
|
|
if (!testRunner.NameExists(partName, 1) && !string.IsNullOrEmpty(containerName))
|
2017-10-26 15:05:46 -07:00
|
|
|
|
{
|
|
|
|
|
|
testRunner.NavigateToFolder(containerName);
|
|
|
|
|
|
}
|
2017-06-02 19:40:10 -07:00
|
|
|
|
|
2017-10-27 14:19:26 -07:00
|
|
|
|
var partWidget = testRunner.GetWidgetByName(partName, out _) as ListViewItemBase;
|
|
|
|
|
|
if (!partWidget.IsSelected)
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName(partName);
|
|
|
|
|
|
}
|
|
|
|
|
|
testRunner.ClickByName("Print Library Overflow Menu");
|
2017-10-31 11:22:58 -07:00
|
|
|
|
|
|
|
|
|
|
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
|
|
|
|
|
|
var scene = view3D.InteractionLayer.Scene;
|
|
|
|
|
|
var preAddCount = scene.Children.Count();
|
|
|
|
|
|
|
2017-10-27 14:19:26 -07:00
|
|
|
|
testRunner.ClickByName("Add to Plate Menu Item");
|
2017-10-31 11:22:58 -07:00
|
|
|
|
// wait for the object to be added
|
2017-12-15 20:24:58 -08:00
|
|
|
|
testRunner.WaitFor(() => scene.Children.Count == preAddCount + 1);
|
2017-10-31 11:22:58 -07:00
|
|
|
|
// wait for the object to be done loading
|
|
|
|
|
|
var insertionGroup = scene.Children.LastOrDefault() as InsertionGroup;
|
2017-12-06 17:23:21 -08:00
|
|
|
|
if (insertionGroup != null)
|
2017-10-31 11:22:58 -07:00
|
|
|
|
{
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => scene.Children.LastOrDefault() as InsertionGroup != null, 10);
|
2017-10-31 11:22:58 -07:00
|
|
|
|
}
|
2017-06-04 08:57:17 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-06 18:19:02 -07:00
|
|
|
|
public static void SaveBedplateToFolder(this AutomationRunner testRunner, string newFileName, string folderName)
|
|
|
|
|
|
{
|
2017-08-30 16:43:58 -07:00
|
|
|
|
testRunner.ClickByName("Bed Options Menu");
|
2017-06-06 18:19:02 -07:00
|
|
|
|
testRunner.ClickByName("Save As Menu Item");
|
|
|
|
|
|
|
|
|
|
|
|
testRunner.Delay(1);
|
|
|
|
|
|
|
|
|
|
|
|
testRunner.Type(newFileName);
|
|
|
|
|
|
|
|
|
|
|
|
testRunner.NavigateToFolder(folderName);
|
|
|
|
|
|
|
|
|
|
|
|
testRunner.ClickByName("Save As Save Button");
|
|
|
|
|
|
|
|
|
|
|
|
// Give the SaveAs window time to close before returning to the caller
|
|
|
|
|
|
testRunner.Delay(2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-16 17:58:46 -07:00
|
|
|
|
public static void WaitForPrintFinished(this AutomationRunner testRunner, int maxSeconds = 500)
|
2017-06-02 21:20:56 -07:00
|
|
|
|
{
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => ApplicationController.Instance.ActivePrinter.Connection.CommunicationState == CommunicationStates.FinishedPrint, maxSeconds);
|
2017-09-16 17:58:46 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void WaitForCommunicationStateDisconnected(this AutomationRunner testRunner, int maxSeconds = 500)
|
|
|
|
|
|
{
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => ApplicationController.Instance.ActivePrinter.Connection.CommunicationState == CommunicationStates.Disconnected, maxSeconds);
|
2017-06-02 21:20:56 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-25 06:17:37 -07:00
|
|
|
|
public static async Task RunTest(
|
|
|
|
|
|
AutomationTest testMethod,
|
2016-09-20 14:32:22 -07:00
|
|
|
|
string staticDataPathOverride = null,
|
|
|
|
|
|
double maxTimeToRun = 60,
|
2016-08-02 09:47:26 -07:00
|
|
|
|
QueueTemplate queueItemFolderToAdd = QueueTemplate.None,
|
2017-12-06 17:23:21 -08:00
|
|
|
|
int overrideWidth = -1,
|
2016-10-07 13:49:01 -07:00
|
|
|
|
int overrideHeight = -1,
|
|
|
|
|
|
string defaultTestImages = null)
|
2015-09-04 11:28:01 -07:00
|
|
|
|
{
|
2016-10-17 11:02:40 -07:00
|
|
|
|
// Walk back a step in the stack and output the callers name
|
2017-12-06 15:21:18 -08:00
|
|
|
|
//StackTrace st = new StackTrace(false);
|
|
|
|
|
|
//Debug.WriteLine("\r\n ***** Running automation test: {0} {1} ", st.GetFrames().Skip(1).First().GetMethod().Name, DateTime.Now);
|
2016-10-17 11:02:40 -07:00
|
|
|
|
|
2015-09-04 11:28:01 -07:00
|
|
|
|
if (staticDataPathOverride == null)
|
|
|
|
|
|
{
|
2016-09-20 09:39:57 -07:00
|
|
|
|
// Popping one directory above MatterControl, then back down into MatterControl ensures this works in MCCentral as well and MatterControl
|
|
|
|
|
|
staticDataPathOverride = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "StaticData");
|
2015-09-04 11:28:01 -07:00
|
|
|
|
}
|
2015-12-22 11:34:04 -08:00
|
|
|
|
|
2016-10-17 11:02:40 -07:00
|
|
|
|
#if DEBUG
|
|
|
|
|
|
string outputDirectory = "Debug";
|
|
|
|
|
|
#else
|
|
|
|
|
|
string outputDirectory = "Release";
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2017-12-05 18:05:18 -08:00
|
|
|
|
Environment.CurrentDirectory = TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl", "bin", outputDirectory);
|
|
|
|
|
|
|
|
|
|
|
|
// Override the default SystemWindow type without config.json
|
|
|
|
|
|
AggContext.Config.ProviderTypes.SystemWindow = "MatterHackers.Agg.UI.OpenGLSystemWindow, agg_platform_win32";
|
2016-10-17 11:02:40 -07:00
|
|
|
|
|
2015-09-04 11:28:01 -07:00
|
|
|
|
#if !__ANDROID__
|
|
|
|
|
|
// Set the static data to point to the directory of MatterControl
|
2017-08-20 02:34:39 -07:00
|
|
|
|
AggContext.StaticData = new FileSystemStaticData(staticDataPathOverride);
|
2015-09-04 11:28:01 -07:00
|
|
|
|
#endif
|
2016-09-20 09:39:57 -07:00
|
|
|
|
// Popping one directory above MatterControl, then back down into MatterControl ensures this works in MCCentral as well and MatterControl
|
|
|
|
|
|
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(5, "MatterControl"));
|
2015-10-22 18:23:22 -07:00
|
|
|
|
|
2015-12-22 11:34:04 -08:00
|
|
|
|
if (queueItemFolderToAdd != QueueTemplate.None)
|
2015-10-22 18:23:22 -07:00
|
|
|
|
{
|
2017-06-04 17:39:30 -07:00
|
|
|
|
MatterControlUtilities.AddItemsToQueue(queueItemFolderToAdd.ToString());
|
2015-10-22 18:23:22 -07:00
|
|
|
|
}
|
2015-09-04 11:28:01 -07:00
|
|
|
|
|
2016-10-19 11:49:52 -07:00
|
|
|
|
if (defaultTestImages == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
defaultTestImages = TestContext.CurrentContext.ResolveProjectPath(4, "Tests", "TestData", "TestImages");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-12-02 10:52:33 -08:00
|
|
|
|
UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, "orthographic");
|
2016-12-07 15:24:48 -08:00
|
|
|
|
//GL.HardwareAvailable = false;
|
2016-10-19 13:27:27 -07:00
|
|
|
|
|
|
|
|
|
|
var config = TestAutomationConfig.Load();
|
2017-12-06 17:23:21 -08:00
|
|
|
|
if (config.UseAutomationDialogs)
|
|
|
|
|
|
{
|
|
|
|
|
|
AggContext.Config.ProviderTypes.DialogProvider = "MatterHackers.Agg.Platform.AutomationDialogProvider, GuiAutomation";
|
|
|
|
|
|
}
|
2017-12-06 09:14:32 -08:00
|
|
|
|
|
2016-12-13 10:20:12 -08:00
|
|
|
|
// Extract mouse speed from config
|
|
|
|
|
|
AutomationRunner.TimeToMoveMouse = config.TimeToMoveMouse;
|
2017-12-06 17:23:21 -08:00
|
|
|
|
AutomationRunner.UpDelaySeconds = config.MouseUpDelay;
|
2016-12-13 10:20:12 -08:00
|
|
|
|
|
2017-12-18 22:03:17 -08:00
|
|
|
|
var (width, height) = RootSystemWindow.GetStartupBounds();
|
|
|
|
|
|
|
|
|
|
|
|
rootSystemWindow = Application.LoadRootWindow(
|
|
|
|
|
|
overrideWidth == -1 ? width : overrideWidth,
|
|
|
|
|
|
overrideHeight == -1 ? height : overrideHeight);
|
2017-12-16 19:09:25 -08:00
|
|
|
|
|
2017-10-05 18:04:45 -07:00
|
|
|
|
await AutomationRunner.ShowWindowAndExecuteTests(
|
2017-12-16 19:09:25 -08:00
|
|
|
|
rootSystemWindow,
|
2017-12-06 17:23:21 -08:00
|
|
|
|
testMethod,
|
|
|
|
|
|
maxTimeToRun,
|
|
|
|
|
|
defaultTestImages,
|
2017-12-06 15:19:23 -08:00
|
|
|
|
config.UseAutomationMouse ? AutomationRunner.InputType.SimulatedDrawMouse : AutomationRunner.InputType.Native,
|
2017-10-05 18:04:45 -07:00
|
|
|
|
closeWindow: () =>
|
2017-06-11 09:58:25 -07:00
|
|
|
|
{
|
2017-10-05 18:04:45 -07:00
|
|
|
|
if (ApplicationController.Instance.ActivePrinter.Connection.CommunicationState == CommunicationStates.Printing)
|
|
|
|
|
|
{
|
|
|
|
|
|
ApplicationController.Instance.ActivePrinter.Connection.Disable();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-16 19:09:25 -08:00
|
|
|
|
rootSystemWindow.Close();
|
2017-10-05 18:04:45 -07:00
|
|
|
|
});
|
2015-09-04 11:28:01 -07:00
|
|
|
|
}
|
2016-08-01 13:53:28 -07:00
|
|
|
|
|
|
|
|
|
|
public static void LibraryAddSelectionToQueue(AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-06-03 13:29:36 -07:00
|
|
|
|
testRunner.ClickByName("Print Library Overflow Menu");
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Add to Queue Menu Item");
|
2016-08-01 13:53:28 -07:00
|
|
|
|
}
|
2016-08-01 14:22:16 -07:00
|
|
|
|
|
|
|
|
|
|
public static void LibraryEditSelectedItem(AutomationRunner testRunner)
|
|
|
|
|
|
{
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Edit Menu Item");
|
2017-02-01 10:12:31 -08:00
|
|
|
|
testRunner.Delay(1); // wait for the new window to open
|
2016-08-01 14:22:16 -07:00
|
|
|
|
}
|
2016-08-01 17:21:31 -07:00
|
|
|
|
|
2017-06-03 13:29:36 -07:00
|
|
|
|
public static void LibraryRenameSelectedItem(this AutomationRunner testRunner)
|
2016-08-01 17:21:31 -07:00
|
|
|
|
{
|
2017-06-03 13:29:36 -07:00
|
|
|
|
testRunner.ClickByName("Print Library Overflow Menu");
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Rename Menu Item");
|
2016-08-01 17:21:31 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-06 18:52:13 -07:00
|
|
|
|
public static void LibraryRemoveSelectedItem(this AutomationRunner testRunner)
|
2016-08-01 17:21:31 -07:00
|
|
|
|
{
|
2017-06-03 13:29:36 -07:00
|
|
|
|
testRunner.ClickByName("Print Library Overflow Menu");
|
2017-06-14 09:56:51 -07:00
|
|
|
|
testRunner.ClickByName("Remove Menu Item");
|
2016-08-01 17:21:31 -07:00
|
|
|
|
}
|
2017-06-03 13:29:36 -07:00
|
|
|
|
|
2016-09-20 09:39:57 -07:00
|
|
|
|
public static string ResolveProjectPath(this TestContext context, int stepsToProjectRoot, params string[] relativePathSteps)
|
|
|
|
|
|
{
|
|
|
|
|
|
string assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|
|
|
|
|
|
|
|
|
|
|
var allPathSteps = new List<string> { assemblyPath };
|
|
|
|
|
|
allPathSteps.AddRange(Enumerable.Repeat("..", stepsToProjectRoot));
|
|
|
|
|
|
|
|
|
|
|
|
if (relativePathSteps.Any())
|
|
|
|
|
|
{
|
|
|
|
|
|
allPathSteps.AddRange(relativePathSteps);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Path.GetFullPath(Path.Combine(allPathSteps.ToArray()));
|
|
|
|
|
|
}
|
2016-09-21 15:34:53 -07:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Set the working directory to the location of the executing assembly. This is essentially the Nunit2 behavior
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="context"></param>
|
|
|
|
|
|
public static void SetCompatibleWorkingDirectory(this TestContext context)
|
|
|
|
|
|
{
|
|
|
|
|
|
Environment.CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
|
|
|
|
|
}
|
2016-09-20 14:32:22 -07:00
|
|
|
|
|
2017-09-23 00:26:50 -07:00
|
|
|
|
public static void StartSlicing(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Generate Gcode Button");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-14 16:19:22 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Switch to the primary SliceSettings tab
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner"></param>
|
|
|
|
|
|
public static void OpenPrintPopupMenu(this AutomationRunner testRunner)
|
2016-09-20 14:32:22 -07:00
|
|
|
|
{
|
2017-12-14 16:19:22 -08:00
|
|
|
|
var printerConnection = ApplicationController.Instance.ActivePrinter.Connection;
|
|
|
|
|
|
|
2017-12-14 21:59:41 -08:00
|
|
|
|
if (printerConnection.CommunicationState != CommunicationStates.Connected
|
|
|
|
|
|
&& printerConnection.CommunicationState != CommunicationStates.FinishedPrint)
|
2017-12-14 16:19:22 -08:00
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Connect to printer button");
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => printerConnection.CommunicationState == CommunicationStates.Connected);
|
2017-12-14 16:19:22 -08:00
|
|
|
|
}
|
2017-06-12 20:35:48 -07:00
|
|
|
|
|
2017-12-15 08:54:59 -08:00
|
|
|
|
// Wait for button to become enabled
|
|
|
|
|
|
var printerPopup = testRunner.GetWidgetByName("PrintPopupMenu", out _);
|
2017-12-15 19:28:25 -08:00
|
|
|
|
testRunner.WaitFor(() => printerPopup.Enabled);
|
2017-12-15 08:54:59 -08:00
|
|
|
|
|
2017-12-14 16:19:22 -08:00
|
|
|
|
testRunner.ClickByName("PrintPopupMenu");
|
|
|
|
|
|
}
|
2017-06-02 19:39:29 -07:00
|
|
|
|
|
2017-12-14 16:19:22 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Open the Print popup menu and click the Start Print button
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner"></param>
|
|
|
|
|
|
public static void StartPrint(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.OpenPrintPopupMenu();
|
|
|
|
|
|
testRunner.ClickByName("Start Print Button");
|
|
|
|
|
|
}
|
2017-06-09 20:12:25 -07:00
|
|
|
|
|
2017-12-14 16:19:22 -08:00
|
|
|
|
public static void OpenGCode3DOverflowMenu(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
|
|
|
|
|
var button = testRunner.GetWidgetByName("Layers3D Button", out _) as ICheckbox;
|
|
|
|
|
|
if (!button.Checked)
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Layers3D Button");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
testRunner.ClickByName("View3D Overflow Menu");
|
2016-09-20 14:32:22 -07:00
|
|
|
|
}
|
2017-06-04 08:22:04 -07:00
|
|
|
|
|
2017-12-14 16:19:22 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Switch to the primary SliceSettings tab
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner"></param>
|
|
|
|
|
|
public static void SwitchToSliceSettings(this AutomationRunner testRunner)
|
|
|
|
|
|
{
|
|
|
|
|
|
EnsurePrinterSidebarOpen(testRunner);
|
|
|
|
|
|
testRunner.ClickByName("General Tab");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Switch to Printer -> Controls
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner"></param>
|
2017-06-13 13:22:22 -07:00
|
|
|
|
public static void SwitchToControlsTab(this AutomationRunner testRunner)
|
2017-12-14 16:19:22 -08:00
|
|
|
|
{
|
|
|
|
|
|
// Change to Printer Controls
|
|
|
|
|
|
EnsurePrinterSidebarOpen(testRunner);
|
|
|
|
|
|
testRunner.ClickByName("Controls Tab");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void EnsurePrinterSidebarOpen(AutomationRunner testRunner)
|
2017-06-13 13:22:22 -07:00
|
|
|
|
{
|
|
|
|
|
|
// If the sidebar exists, we need to expand and pin it
|
|
|
|
|
|
if (testRunner.WaitForName("Slice Settings Sidebar", 0.2))
|
|
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName("Slice Settings Sidebar");
|
|
|
|
|
|
testRunner.ClickByName("Pin Settings Button");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-04 08:22:04 -07:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Adds the given asset names to the local library and validates the result
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner"></param>
|
|
|
|
|
|
/// <param name="assetNames">The test assets to add to the library</param>
|
|
|
|
|
|
public static void AddTestAssetsToLibrary(this AutomationRunner testRunner, params string[] assetNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Switch to the Local Library tab
|
|
|
|
|
|
testRunner.NavigateToFolder("Local Library Row Item Collection");
|
|
|
|
|
|
|
2017-09-23 12:23:48 -07:00
|
|
|
|
// Assert that the requested items are *not* in the list
|
2017-06-04 08:22:04 -07:00
|
|
|
|
foreach (string assetName in assetNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
string friendlyName = Path.GetFileNameWithoutExtension(assetName);
|
2017-12-06 17:23:21 -08:00
|
|
|
|
Assert.IsFalse(testRunner.WaitForName($"Row Item {friendlyName}", .1), $"{friendlyName} part should not exist at test start");
|
2017-06-04 08:22:04 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add Library item
|
|
|
|
|
|
testRunner.ClickByName("Library Add Button");
|
2017-12-06 17:23:21 -08:00
|
|
|
|
|
|
|
|
|
|
// Generate the full, quoted paths for the requested assets
|
|
|
|
|
|
string fullQuotedAssetPaths = string.Join(" ", assetNames.Select(name => $"\"{MatterControlUtilities.GetTestItemPath(name)}\""));
|
|
|
|
|
|
testRunner.CompleteDialog(fullQuotedAssetPaths);
|
2017-06-04 08:22:04 -07:00
|
|
|
|
|
2017-09-23 12:23:48 -07:00
|
|
|
|
// Assert that the added items *are* in the list
|
2017-06-04 08:22:04 -07:00
|
|
|
|
foreach (string assetName in assetNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
string friendlyName = Path.GetFileNameWithoutExtension(assetName);
|
2017-09-23 12:23:48 -07:00
|
|
|
|
Assert.IsTrue(testRunner.WaitForName($"Row Item {friendlyName}"), $"{friendlyName} part should exist after adding");
|
2017-06-04 08:22:04 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-06-06 18:42:44 -07:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Control clicks each specified item
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="testRunner"></param>
|
|
|
|
|
|
/// <param name="widgetNames">The widgets to click</param>
|
|
|
|
|
|
public static void SelectListItems(this AutomationRunner testRunner, params string[] widgetNames)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Control click all items
|
|
|
|
|
|
Keyboard.SetKeyDownState(Keys.ControlKey, down: true);
|
2017-12-06 17:23:21 -08:00
|
|
|
|
foreach (var widgetName in widgetNames)
|
2017-06-06 18:42:44 -07:00
|
|
|
|
{
|
|
|
|
|
|
testRunner.ClickByName(widgetName);
|
|
|
|
|
|
}
|
|
|
|
|
|
Keyboard.SetKeyDownState(Keys.ControlKey, down: false);
|
|
|
|
|
|
}
|
2016-09-20 14:32:22 -07:00
|
|
|
|
}
|
2015-12-22 11:34:04 -08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Represents a queue template folder on disk (located at Tests/TestData/QueueItems) that should be synced into the default
|
|
|
|
|
|
/// queue during test init. The enum name and folder name *must* be the same in order to function
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public enum QueueTemplate
|
|
|
|
|
|
{
|
|
|
|
|
|
None,
|
|
|
|
|
|
Three_Queue_Items
|
|
|
|
|
|
}
|
2016-09-20 09:39:57 -07:00
|
|
|
|
|
|
|
|
|
|
public class TestAutomationConfig
|
|
|
|
|
|
{
|
|
|
|
|
|
private static readonly string configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "MHTest.config");
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The ClientToken used by tests to emulate an external client
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string TestEnvClientToken { get; set; }
|
|
|
|
|
|
|
2016-12-13 10:20:12 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The number of seconds to move the mouse when going to a new position.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public double TimeToMoveMouse { get; set; } = .5;
|
|
|
|
|
|
|
2017-12-06 15:19:23 -08:00
|
|
|
|
public bool UseAutomationDialogs { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public bool UseAutomationMouse { get; set; }
|
|
|
|
|
|
|
2017-12-06 17:23:21 -08:00
|
|
|
|
public double MouseUpDelay { get; set; } = 0.2;
|
|
|
|
|
|
|
2017-12-15 18:19:36 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The number of seconds the emulator should take to heat up and given target
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public double HeatupTime { get; set; } = 0.5;
|
|
|
|
|
|
|
2017-12-15 19:21:50 -08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// The number of seconds to wait after reaching the target temp before continuing. Analogous to
|
|
|
|
|
|
/// firmware dwell time for temperature stabilization
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public double TempStabilizationTime { get; set; } = 0.5;
|
|
|
|
|
|
|
2017-12-06 15:19:23 -08:00
|
|
|
|
public static TestAutomationConfig Load()
|
2016-09-20 09:39:57 -07:00
|
|
|
|
{
|
|
|
|
|
|
TestAutomationConfig config = null;
|
|
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(configPath))
|
|
|
|
|
|
{
|
|
|
|
|
|
config = new TestAutomationConfig();
|
|
|
|
|
|
config.Save();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
config = JsonConvert.DeserializeObject<TestAutomationConfig>(File.ReadAllText(configPath));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return config;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Persist the current settings to the 'MHTest.config' in the user profile - %userprofile%\MHTest.config
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void Save()
|
|
|
|
|
|
{
|
|
|
|
|
|
File.WriteAllText(configPath, JsonConvert.SerializeObject(this, Formatting.Indented));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2015-05-07 19:57:33 -07:00
|
|
|
|
}
|