799 lines
27 KiB
C#
799 lines
27 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using MatterHackers.Agg;
|
|
using MatterHackers.Agg.UI;
|
|
using MatterHackers.GuiAutomation;
|
|
using MatterHackers.MatterControl.PrinterCommunication;
|
|
using MatterHackers.MatterControl.PrinterCommunication.Io;
|
|
using MatterHackers.MatterControl.PrintHistory;
|
|
using MatterHackers.MatterControl.SlicerConfiguration;
|
|
using MatterHackers.PrinterEmulator;
|
|
using MatterHackers.VectorMath;
|
|
using NUnit.Framework;
|
|
using TestInvoker;
|
|
|
|
namespace MatterHackers.MatterControl.Tests.Automation
|
|
{
|
|
[TestFixture, Category("MatterControl.UI.Automation"), Parallelizable(ParallelScope.Children)]
|
|
public class PrintingTests
|
|
{
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task CompletingPrintTurnsoffHeat()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
testRunner.WaitForName("Cancel Wizard Button", 1);
|
|
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should be defined after add");
|
|
|
|
testRunner.SelectSliceSettingsField(SettingsKey.end_gcode);
|
|
|
|
testRunner.Type("^a");
|
|
testRunner.Type("{BACKSPACE}");
|
|
testRunner.Type("G28");
|
|
|
|
testRunner.SelectSliceSettingsField(SettingsKey.start_gcode);
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
// TODO: Failure persisting GCode / MultilineTextField value
|
|
// Expected string length 3 but was 2.Strings differ at index 0.
|
|
// Shift-G is being swallowed by something.
|
|
|
|
// Validate GCode fields persist values
|
|
Assert.AreEqual(
|
|
"G28",
|
|
printer.Settings.GetValue(SettingsKey.end_gcode),
|
|
"Failure persisting GCode/MultilineTextField value");
|
|
|
|
testRunner.AddItemToBed();
|
|
|
|
// Shorten the delay so the test runs in a reasonable time
|
|
printer.Connection.TimeToHoldTemperature = 5;
|
|
|
|
testRunner.StartPrint(printer);
|
|
|
|
// Wait for print to finish
|
|
testRunner.WaitForPrintFinished(printer);
|
|
|
|
// Wait for expected temp
|
|
testRunner.WaitFor(() => printer.Connection.GetActualHotendTemperature(0) <= 0, 10);
|
|
Assert.Less(printer.Connection.GetActualHotendTemperature(0), 30);
|
|
|
|
// Wait for expected temp
|
|
testRunner.WaitFor(() => printer.Connection.ActualBedTemperature <= 10);
|
|
Assert.Less(printer.Connection.ActualBedTemperature, 10);
|
|
|
|
// Make sure we can run this whole thing again
|
|
testRunner.StartPrint(printer);
|
|
|
|
// Wait for print to finish
|
|
testRunner.WaitForPrintFinished(printer);
|
|
|
|
// Wait for expected temp
|
|
testRunner.WaitFor(() => printer.Connection.GetActualHotendTemperature(0) <= 0, 10);
|
|
Assert.Less(printer.Connection.GetActualHotendTemperature(0), 30);
|
|
|
|
// Wait for expected temp
|
|
testRunner.WaitFor(() => printer.Connection.ActualBedTemperature <= 10);
|
|
Assert.Less(printer.Connection.ActualBedTemperature, 10);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 95);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task PulseLevelingTest()
|
|
{
|
|
// Validates the Pulse profile requires leveling and it works as expected
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
AutomationRunner.TimeToMoveMouse = .2;
|
|
testRunner.WaitForName("Cancel Wizard Button", 1);
|
|
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator("Pulse", "A-134"))
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should be defined after add");
|
|
|
|
testRunner.OpenPrintPopupMenu()
|
|
.ClickByName("SetupPrinter")
|
|
.Complete9StepLeveling()
|
|
.AddItemToBed();
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
var currentSettings = printer.Settings;
|
|
currentSettings.SetValue(SettingsKey.pause_gcode, "");
|
|
currentSettings.SetValue(SettingsKey.resume_gcode, "");
|
|
|
|
testRunner.StartPrint(printer, pauseAtLayers: "2");
|
|
|
|
testRunner.WaitForName("Yes Button", 20); // the yes button is 'Resume'
|
|
|
|
// the user types in the pause layer 1 based and we are 0 based, so we should be on: user 2, printer 1.
|
|
Assert.AreEqual(1, printer.Connection.CurrentlyPrintingLayer);
|
|
|
|
// assert the leveling is working
|
|
Assert.AreEqual(11.25, emulator.Destination.Z);
|
|
|
|
testRunner.CancelPrint();
|
|
|
|
// now run leveling again and make sure we get the same result
|
|
testRunner.SwitchToControlsTab();
|
|
testRunner.ClickByName("Printer Calibration Button");
|
|
|
|
testRunner.ClickByName("Print Leveling Row");
|
|
|
|
testRunner.Complete9StepLeveling(2);
|
|
|
|
testRunner.StartPrint(printer, pauseAtLayers: "2");
|
|
|
|
testRunner.WaitForName("Yes Button", 20); // the yes button is 'Resume'
|
|
|
|
// the user types in the pause layer 1 based and we are 0 based, so we should be on: user 2, printer 1.
|
|
Assert.AreEqual(1, printer.Connection.CurrentlyPrintingLayer);
|
|
// assert the leveling is working
|
|
Assert.AreEqual(12.25, emulator.Destination.Z);
|
|
|
|
// NOTE: System.Exception : WaitForWidgetEnabled Failed: Named GuiWidget not found [Print Progress Dial]
|
|
// Might be fixed in CancelPrint now.
|
|
testRunner.CancelPrint();
|
|
|
|
// now modify the leveling data manually and assert that it is applied when printing
|
|
testRunner.SwitchToControlsTab();
|
|
|
|
testRunner.ClickByName("Printer Calibration Button");
|
|
|
|
testRunner.ClickByName("Edit Leveling Data Button");
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
var name = $"z Position {i}";
|
|
testRunner.ClickByName(name);
|
|
testRunner.Type("^a"); // select all
|
|
testRunner.Type("5");
|
|
}
|
|
|
|
testRunner.ClickByName("Save Leveling Button");
|
|
|
|
testRunner.ClickByName("Cancel Wizard Button");
|
|
|
|
testRunner.StartPrint(printer, pauseAtLayers: "2");
|
|
|
|
testRunner.WaitForName("Yes Button", 20); // the yes button is 'Resume'
|
|
|
|
// the user types in the pause layer 1 based and we are 0 based, so we should be on: user 2, printer 1.
|
|
Assert.AreEqual(1, printer.Connection.CurrentlyPrintingLayer);
|
|
|
|
// assert the leveling is working
|
|
Assert.AreEqual(5.25, emulator.Destination.Z);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 230);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public void ExpectedEmulatorResponses()
|
|
{
|
|
// TODO: Emulator behavior should emulate actual printer firmware and use configuration rather than M104/M109 sends to set extruder count
|
|
//
|
|
// Quirky emulator returns single extruder M105 responses until after the first M104, at which point it extends its extruder count to match
|
|
string M105ResponseBeforeM104 = "ok T:27.0 / 0.0";
|
|
string M105ResponseAfterM104 = "ok T0:27.0 / 0.0 T1:27.0 / 0.0";
|
|
|
|
string[] test1 = new string[]
|
|
{
|
|
"N1 M110 N1 * 125",
|
|
"ok",
|
|
"N2 M114 * 37",
|
|
"X:0.00 Y: 0.00 Z: 0.00 E: 0.00 Count X: 0.00 Y: 0.00 Z: 0.00",
|
|
"ok",
|
|
"N3 M105 * 36",
|
|
M105ResponseBeforeM104,
|
|
"N1 M110 N1*125",
|
|
"ok",
|
|
"N2 M115 * 36",
|
|
"MatterControl Printer Emulator",
|
|
"Commands:",
|
|
" SLOW // make the emulator simulate actual printing speeds (default)",
|
|
" FAST // run as fast as possible",
|
|
" THROWERROR // generate a simulated error for testing",
|
|
"Emulating:",
|
|
"FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:https://github.com/MarlinFirmware/Marlin PROTOCOL_VERSION:1.0 MACHINE_TYPE:Framelis v1 EXTRUDER_COUNT:1 UUID:155f84b5-d4d7-46f4-9432-667e6876f37a",
|
|
"ok",
|
|
"N3 M104 T0 S0 * 34",
|
|
"ok",
|
|
"N4 M104 T1 S0 * 36",
|
|
"ok",
|
|
"N5 M105 * 34",
|
|
M105ResponseAfterM104,
|
|
"N6 M105 * 45",
|
|
"Error:checksum mismatch, Last Line: 5",
|
|
"Resend: 6",
|
|
"ok",
|
|
"N6 M105 * 33",
|
|
M105ResponseAfterM104,
|
|
"N7 M105 * 32",
|
|
M105ResponseAfterM104,
|
|
"N8 M105 * 47",
|
|
M105ResponseAfterM104,
|
|
"N9 M105 * 46",
|
|
M105ResponseAfterM104,
|
|
"N10 M105 * 22",
|
|
M105ResponseAfterM104,
|
|
"N11 M105 * 23",
|
|
M105ResponseAfterM104,
|
|
"N12 M105 * 20",
|
|
M105ResponseAfterM104,
|
|
"N13 M105 * 21",
|
|
M105ResponseAfterM104,
|
|
"N14 M105 * 18",
|
|
M105ResponseAfterM104,
|
|
"N15 M105 * 19",
|
|
M105ResponseAfterM104,
|
|
"N16 M105 * 16",
|
|
M105ResponseAfterM104,
|
|
"N17 M105 * 40",
|
|
"Error:checksum mismatch, Last Line: 16",
|
|
"Resend: 17",
|
|
"ok",
|
|
"N17 M105 * 17",
|
|
M105ResponseAfterM104,
|
|
};
|
|
|
|
string[] test2 = new string[]
|
|
{
|
|
"N1 M110 N1*125",
|
|
"ok",
|
|
"N1 M110 N1*125",
|
|
"ok",
|
|
"N1 M110 N1*125",
|
|
"ok",
|
|
"N2 M114*37",
|
|
"X:0.00 Y: 0.00 Z: 0.00 E: 0.00 Count X: 0.00 Y: 0.00 Z: 0.00",
|
|
"ok",
|
|
};
|
|
|
|
SimulatePrint(test1);
|
|
SimulatePrint(test2);
|
|
}
|
|
|
|
private static void SimulatePrint(string[] sendRecieveLog)
|
|
{
|
|
using (var emulator = new Emulator())
|
|
{
|
|
emulator.HasHeatedBed = false;
|
|
|
|
int lineIndex = 0;
|
|
while (lineIndex < sendRecieveLog.Length)
|
|
{
|
|
var sentCommand = sendRecieveLog[lineIndex];
|
|
string response = emulator.GetCorrectResponse(sentCommand);
|
|
lineIndex++;
|
|
var lines = response.Split('\n');
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
if (!string.IsNullOrEmpty(lines[i]))
|
|
{
|
|
Assert.AreEqual(sendRecieveLog[lineIndex], lines[i]);
|
|
lineIndex++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task PrinterRequestsResumeWorkingAsExpected()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should be defined after add");
|
|
|
|
// print a part
|
|
testRunner.AddItemToBed();
|
|
|
|
testRunner.StartPrint(testRunner.FirstPrinter(), pauseAtLayers: "2;6");
|
|
|
|
// turn on line error simulation
|
|
emulator.SimulateLineErrors = true;
|
|
|
|
// close the pause dialog pop-up (resume)
|
|
testRunner.WaitForName("Yes Button", 20); // the yes button is 'Resume'
|
|
testRunner.ClickByName("Yes Button");
|
|
|
|
// simulate board reboot
|
|
emulator.SimulateReboot();
|
|
|
|
// close the pause dialog pop-up (resume)
|
|
testRunner.Delay(3);
|
|
testRunner.WaitForName("Yes Button", 20);
|
|
testRunner.ClickByName("Yes Button");
|
|
|
|
// Wait for done
|
|
testRunner.WaitForPrintFinished(testRunner.FirstPrinter());
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 90 * 2); // Once timed out at 90.
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task PrinterDeletedWhilePrinting()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should exist after add");
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
// print a part
|
|
testRunner.AddItemToBed();
|
|
testRunner.StartPrint(printer, pauseAtLayers: "2");
|
|
ProfileManager.DebugPrinterDelete = true;
|
|
|
|
// Wait for pause dialog
|
|
testRunner.ClickResumeButton(printer, true, 1);
|
|
|
|
// Wait for done
|
|
testRunner.WaitForPrintFinished(printer);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 180);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task PrinterRecoveryTest()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should exist after add");
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
printer.Settings.SetValue(SettingsKey.recover_is_enabled, "1");
|
|
printer.Settings.SetValue(SettingsKey.has_hardware_leveling, "0");
|
|
|
|
Assert.IsTrue(printer.Connection.RecoveryIsEnabled);
|
|
|
|
// print a part
|
|
testRunner.AddItemToBed()
|
|
.StartPrint(printer, pauseAtLayers: "2;4;6")
|
|
.ClickResumeButton(printer, true, 1) // Resume
|
|
.ClickResumeButton(printer, false, 3) // close the pause dialog pop-up do not resume
|
|
.ClickByName("Disconnect from printer button")
|
|
.ClickByName("Yes Button") // accept the disconnect
|
|
//.ClickByName("Cancel Wizard Button") // click the close on the collect info dialog
|
|
.ClickByName("Connect to printer button") // Reconnect
|
|
.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Connected);
|
|
|
|
// Assert that recovery happens
|
|
Assert.IsTrue(PrintRecovery.RecoveryAvailable(printer), "Recovery should be enabled after Disconnect while printing");
|
|
|
|
// Recover the print
|
|
testRunner.ClickButton("Yes Button", "Recover Print")
|
|
.ClickResumeButton(printer, true, 5) // The first pause that we get after recovery should be layer 6.
|
|
.WaitForPrintFinished(printer);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 180);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task TemperatureTowerWorks()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should exist after add");
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
bool foundTemp = false;
|
|
printer.Connection.LineSent += (s, e) =>
|
|
{
|
|
if (e.Contains("M104 S222.2"))
|
|
{
|
|
foundTemp = true;
|
|
}
|
|
};
|
|
|
|
// print a part
|
|
testRunner.AddItemToBed()
|
|
.AddItemToBed("Scripting Row Item Collection", "Row Item Set Temperature")
|
|
.DragDropByName("MoveInZControl", "MoveInZControl", offsetDrag: new Point2D(0, 0), offsetDrop: new Point2D(0, 10))
|
|
.ClickByName("Temperature Edit")
|
|
.Type("222.2")
|
|
.StartPrint(printer)
|
|
.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.FinishedPrint, 60);
|
|
// TODO: finish export test
|
|
//.ExportPrintAndLoadGCode(printer, out string gcode);
|
|
|
|
Assert.IsTrue(foundTemp);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 180);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task RecoveryT1NoProbe()
|
|
{
|
|
await ExtruderT1RecoveryTest("Airwolf 3D", "HD");
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task RecoveryT1WithProbe()
|
|
{
|
|
await ExtruderT1RecoveryTest("FlashForge", "Creator Dual");
|
|
}
|
|
|
|
public async Task ExtruderT1RecoveryTest(string make, string model)
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator(make, model))
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should exist after add");
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
testRunner.ChangeSettings(
|
|
new (string, string)[]
|
|
{
|
|
(SettingsKey.recover_is_enabled, "1"),
|
|
(SettingsKey.extruder_count, "2"),
|
|
(SettingsKey.has_hardware_leveling, "0"),
|
|
}, printer);
|
|
|
|
Assert.IsTrue(printer.Connection.RecoveryIsEnabled);
|
|
|
|
// print a part
|
|
testRunner.AddItemToBed()
|
|
.ClickByName("ItemMaterialButton")
|
|
.ClickByName("Material 2 Button")
|
|
.StartPrint(printer, pauseAtLayers: "2;3;4;5");
|
|
|
|
testRunner.ClickResumeButton(printer, true, 1); // Resume
|
|
// make sure we are printing with extruder 2 (T1)
|
|
Assert.AreEqual(0, printer.Connection.GetTargetHotendTemperature(0));
|
|
Assert.Greater(printer.Connection.GetTargetHotendTemperature(1), 0);
|
|
|
|
testRunner.ClickResumeButton(printer, false, 2) // close the pause dialog pop-up do not resume
|
|
.ClickByName("Disconnect from printer button")
|
|
.ClickByName("Yes Button") // Are you sure?
|
|
.ClickByName("Connect to printer button") // Reconnect
|
|
.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Connected);
|
|
|
|
// Assert that recovery happens
|
|
Assert.IsTrue(PrintRecovery.RecoveryAvailable(printer), "Recovery should be enabled after Disconnect while printing");
|
|
|
|
// Recover the print
|
|
testRunner.ClickButton("Yes Button", "Recover Print");
|
|
|
|
// The first pause that we get after recovery should be layer 4 (index 3).
|
|
testRunner.ClickResumeButton(printer, true, 3);
|
|
// make sure we are printing with extruder 2 (T1)
|
|
Assert.AreEqual(0, printer.Connection.GetTargetHotendTemperature(0));
|
|
Assert.Greater(printer.Connection.GetTargetHotendTemperature(1), 0);
|
|
|
|
testRunner.ClickResumeButton(printer, true, 4);
|
|
|
|
testRunner.WaitForPrintFinished(printer);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 180);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task TuningAdjustmentsDefaultToOneAndPersists()
|
|
{
|
|
double targetExtrusionRate = 1.5;
|
|
double targetFeedRate = 2;
|
|
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
testRunner.WaitForName("Cancel Wizard Button");
|
|
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should be defined after add");
|
|
|
|
testRunner.AddItemToBed();
|
|
|
|
testRunner.SwitchToControlsTab();
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
testRunner.StartPrint(printer)
|
|
.ScrollIntoView("Extrusion Multiplier NumberEdit")
|
|
.ScrollIntoView("Feed Rate NumberEdit");
|
|
|
|
testRunner.PausePrint();
|
|
|
|
// Tuning values should default to 1 when missing
|
|
ConfirmExpectedSpeeds(testRunner, 1, 1, "Initial case");
|
|
|
|
testRunner.Delay()
|
|
.ClickByName("Extrusion Multiplier NumberEdit")
|
|
.Type(targetExtrusionRate.ToString())
|
|
.ClickByName("Feed Rate NumberEdit")
|
|
.Type(targetFeedRate.ToString())
|
|
// Force focus away from the feed rate field, causing an persisted update
|
|
.ClickByName("Extrusion Multiplier NumberEdit");
|
|
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After setting TextEdit values");
|
|
|
|
// Wait for slicing to complete before setting target values
|
|
testRunner.WaitFor(() => printer.Connection.DetailedPrintingState == DetailedPrintingState.Printing, 8);
|
|
testRunner.Delay();
|
|
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "While printing");
|
|
|
|
testRunner.ResumePrint();
|
|
|
|
// Wait up to 60 seconds for the print to finish
|
|
testRunner.WaitForPrintFinished(printer, 60);
|
|
|
|
// Values should match entered values
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After print finished");
|
|
|
|
testRunner.StartPrint(printer) // Restart the print
|
|
.Delay(1);
|
|
|
|
// Values should match entered values
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After print restarted");
|
|
|
|
testRunner.CancelPrint()
|
|
.Delay(1);
|
|
|
|
// Values should match entered values
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After canceled print");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, overrideHeight: 900, maxTimeToRun: 120);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task TuningAdjustmentControlsBoundToStreamValues()
|
|
{
|
|
double targetExtrusionRate = 1.5;
|
|
double targetFeedRate = 2;
|
|
|
|
double initialExtrusionRate = 0.6;
|
|
double initialFeedRate = 0.7;
|
|
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
testRunner.WaitForName("Cancel Wizard Button");
|
|
|
|
// Then validate that they are picked up
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should be defined after add");
|
|
|
|
testRunner.AddItemToBed();
|
|
|
|
testRunner.SwitchToControlsTab();
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
// Set custom adjustment values
|
|
printer.Settings.SetValue(SettingsKey.feedrate_ratio, initialFeedRate.ToString());
|
|
printer.Settings.SetValue(SettingsKey.extrusion_ratio, initialExtrusionRate.ToString());
|
|
|
|
var printFinishedResetEvent = new AutoResetEvent(false);
|
|
printer.Connection.PrintFinished += (s, e) => printFinishedResetEvent.Set();
|
|
|
|
testRunner.StartPrint(printer);
|
|
|
|
testRunner.PausePrint();
|
|
|
|
var container = testRunner.GetWidgetByName("ManualPrinterControls.ControlsContainer", out _, 5);
|
|
|
|
// Scroll the widget into view
|
|
var scrollable = container.Parents<ManualPrinterControls>().FirstOrDefault() as ScrollableWidget;
|
|
var width = scrollable.Width;
|
|
|
|
// Workaround needed to scroll to the bottom of the Controls panel
|
|
// scrollable.ScrollPosition = new Vector2();
|
|
scrollable.ScrollPosition = new Vector2(0, 30);
|
|
|
|
// Workaround to force layout to fix problems with size of Tuning Widgets after setting ScrollPosition manually
|
|
scrollable.Width = width - 1;
|
|
scrollable.Width = width;
|
|
|
|
// Tuning values should match
|
|
ConfirmExpectedSpeeds(testRunner, initialExtrusionRate, initialFeedRate, "Initial case");
|
|
|
|
testRunner.Delay();
|
|
testRunner.ClickByName("Extrusion Multiplier NumberEdit");
|
|
testRunner.Type(targetExtrusionRate.ToString());
|
|
|
|
testRunner.ClickByName("Feed Rate NumberEdit");
|
|
testRunner.Type(targetFeedRate.ToString());
|
|
|
|
// Force focus away from the feed rate field, causing an persisted update
|
|
testRunner.ClickByName("Extrusion Multiplier NumberEdit");
|
|
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After setting TextEdit values");
|
|
|
|
// Wait for slicing to complete before setting target values
|
|
testRunner.WaitFor(() => printer.Connection.DetailedPrintingState == DetailedPrintingState.Printing, 8);
|
|
testRunner.Delay();
|
|
|
|
// Values should remain after print completes
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "While printing");
|
|
|
|
testRunner.ResumePrint();
|
|
|
|
// Wait for printing to complete
|
|
printFinishedResetEvent.WaitOne();
|
|
|
|
testRunner.WaitForPrintFinished(printer);
|
|
|
|
// Values should match entered values
|
|
testRunner.StartPrint(printer);
|
|
testRunner.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Printing, 15);
|
|
|
|
// Values should match entered values
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "While reprinting");
|
|
|
|
testRunner.CancelPrint();
|
|
testRunner.WaitFor(() => printer.Connection.CommunicationState == CommunicationStates.Connected, 15);
|
|
|
|
// Values should match entered values
|
|
ConfirmExpectedSpeeds(testRunner, targetExtrusionRate, targetFeedRate, "After cancel");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, overrideHeight: 900, maxTimeToRun: 120);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task CloseShouldNotStopSDPrint()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
testRunner.WaitForName("Cancel Wizard Button");
|
|
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator(runSlow: true))
|
|
{
|
|
testRunner.NavigateToFolder("SD Card Row Item Collection");
|
|
|
|
testRunner.ClickByName("Row Item Item 1.gcode");
|
|
|
|
testRunner.ClickByName("Print Library Overflow Menu");
|
|
testRunner.ClickByName("Print Menu Item");
|
|
|
|
testRunner.Delay(2);
|
|
|
|
int tempChangedCount = 0;
|
|
int fanChangedCount = 0;
|
|
emulator.ExtruderTemperatureChanged += (s, e) =>
|
|
{
|
|
tempChangedCount++;
|
|
};
|
|
emulator.FanSpeedChanged += (s, e) =>
|
|
{
|
|
fanChangedCount++;
|
|
};
|
|
|
|
testRunner.CloseMatterControl();
|
|
|
|
testRunner.ClickByName("Yes Button");
|
|
|
|
testRunner.Delay(2);
|
|
Assert.AreEqual(0, tempChangedCount, "We should not change this while exiting an sd card print.");
|
|
Assert.AreEqual(0, fanChangedCount, "We should not change this while exiting an sd card print.");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, maxTimeToRun: 90);
|
|
}
|
|
|
|
[Test, ChildProcessTest, Category("Emulator")]
|
|
public async Task CancelingPrintTurnsHeatAndFanOff()
|
|
{
|
|
await MatterControlUtilities.RunTest((testRunner) =>
|
|
{
|
|
testRunner.WaitForName("Cancel Wizard Button");
|
|
|
|
using (var emulator = testRunner.LaunchAndConnectToPrinterEmulator())
|
|
{
|
|
var resetEvent = new AutoResetEvent(false);
|
|
|
|
Assert.AreEqual(1, ApplicationController.Instance.ActivePrinters.Count(), "One printer should exist after add");
|
|
|
|
testRunner.AddItemToBed();
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
testRunner.StartPrint(printer);
|
|
|
|
int fanChangedCount = 0;
|
|
emulator.FanSpeedChanged += (s, e) =>
|
|
{
|
|
fanChangedCount++;
|
|
};
|
|
|
|
emulator.WaitForLayer(printer.Settings, 2);
|
|
emulator.RunSlow = true;
|
|
|
|
// Click close but cancel
|
|
testRunner.CloseMatterControl();
|
|
testRunner.ClickByName("No Button");
|
|
|
|
// Wait for close
|
|
testRunner.WaitForWidgetDisappear("Yes Button", 4);
|
|
testRunner.Delay(2);
|
|
|
|
// Confirm abort
|
|
Assert.IsFalse(AppContext.RootSystemWindow.HasBeenClosed, "Canceling Close dialog should *not* close MatterControl");
|
|
|
|
// Close MatterControl and cancel print
|
|
testRunner.CloseMatterControl();
|
|
testRunner.ClickByName("Yes Button");
|
|
|
|
// Wait for Disconnected CommunicationState which occurs after PrinterConnection.Disable()
|
|
testRunner.WaitForCommunicationStateDisconnected(printer, maxSeconds: 30);
|
|
|
|
// Wait for close
|
|
testRunner.WaitForWidgetDisappear("Yes Button", 4);
|
|
testRunner.Delay(2);
|
|
|
|
// Confirm close
|
|
Assert.IsTrue(AppContext.RootSystemWindow.HasBeenClosed, "Confirming Close dialog *should* close MatterControl");
|
|
|
|
// Wait for M106 change
|
|
testRunner.WaitFor(() => fanChangedCount > 0, 15, 500);
|
|
|
|
// Assert expected temp targets and fan transitions
|
|
Assert.AreEqual(0, (int) emulator.CurrentExtruder.TargetTemperature, "Unexpected target temperature - MC close should call Connection.Disable->TurnOffBedAndExtruders to shutdown heaters");
|
|
Assert.AreEqual(0, (int) emulator.HeatedBed.TargetTemperature, "Unexpected target temperature - MC close should call Connection.Disable->TurnOffBedAndExtruders to shutdown heaters");
|
|
Assert.AreEqual(1, fanChangedCount, "Unexpected fan speed change count - MC close should call Connection.Disable which shuts down fans via M106");
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}, overrideHeight: 900, maxTimeToRun: 90);
|
|
}
|
|
|
|
private static void ConfirmExpectedSpeeds(AutomationRunner testRunner, double targetExtrusionRate, double targetFeedRate, string scope)
|
|
{
|
|
SolidSlider slider;
|
|
|
|
// Assert the UI has the expected values
|
|
slider = testRunner.GetWidgetByName("Extrusion Multiplier Slider", out _) as SolidSlider;
|
|
testRunner.WaitFor(() => targetExtrusionRate == slider.Value);
|
|
|
|
Assert.AreEqual(targetExtrusionRate, slider.Value, $"Unexpected Extrusion Rate Slider Value - {scope}");
|
|
|
|
slider = testRunner.GetWidgetByName("Feed Rate Slider", out _) as SolidSlider;
|
|
testRunner.WaitFor(() => targetFeedRate == slider.Value);
|
|
Assert.AreEqual(targetFeedRate, slider.Value, $"Unexpected Feed Rate Slider Value - {scope}");
|
|
|
|
var printer = testRunner.FirstPrinter();
|
|
|
|
// Assert the changes took effect on the model
|
|
testRunner.WaitFor(() => targetExtrusionRate == printer.Connection.ExtrusionMultiplierStream.ExtrusionRatio);
|
|
Assert.AreEqual(targetExtrusionRate, printer.Connection.ExtrusionMultiplierStream.ExtrusionRatio, $"Unexpected Extrusion Rate - {scope}");
|
|
|
|
testRunner.WaitFor(() => targetFeedRate == printer.Connection.FeedRateMultiplierStream.FeedRateRatio);
|
|
Assert.AreEqual(targetFeedRate, printer.Connection.FeedRateMultiplierStream.FeedRateRatio, $"Unexpected Feed Rate - {scope}");
|
|
}
|
|
}
|
|
}
|