mattercontrol/Tests/MatterControl.AutomationTests/PartPreviewTests.cs
2022-05-02 10:36:21 -07:00

666 lines
29 KiB
C#

/*
Copyright (c) 2022, 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.
*/
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.GuiAutomation;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.DesignTools;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.PrintQueue;
using MatterHackers.VectorMath;
using NUnit.Framework;
namespace MatterHackers.MatterControl.Tests.Automation
{
[TestFixture, Category("MatterControl.UI.Automation"), RunInApplicationDomain, Apartment(ApartmentState.STA)]
public class PartPreviewTests
{
[Test]
public async Task CopyButtonMakesCopyOfPart()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab();
testRunner.AddItemToBed();
// Get View3DWidget
var view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
testRunner.WaitForName("Calibration - Box.stl");
Assert.AreEqual(1, scene.Children.Count, "Should have 1 part before copy");
// Select scene object
testRunner.Select3DPart("Calibration - Box.stl")
// Click Copy button and count Scene.Children
.ClickByName("Duplicate Button")
.Assert(() => scene.Children.Count == 2, "Should have 2 parts after copy");
// Click Copy button a second time and count Scene.Children
testRunner.ClickByName("Duplicate Button");
testRunner.Assert(() => scene.Children.Count == 3, "Should have 3 parts after 2nd copy");
return Task.CompletedTask;
}, overrideWidth: 1300, maxTimeToRun: 60);
}
[Test]
public async Task AddMultiplePartsMultipleTimes()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab();
var parts = new[]
{
"Row Item Cone",
"Row Item Sphere",
"Row Item Torus"
};
testRunner.AddPrimitivePartsToBed(parts, multiSelect: true);
var view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
testRunner.WaitForName("Selection");
Assert.AreEqual(1, scene.Children.Count, $"Should have 1 scene item after first AddToBed");
testRunner.ClickByName("Print Library Overflow Menu");
testRunner.ClickByName("Add to Bed Menu Item");
testRunner.WaitForName("Selection");
Assert.AreEqual(parts.Length + 1, scene.Children.Count, $"Should have {parts.Length + 1} scene items after second AddToBed");
return Task.CompletedTask;
}, overrideWidth: 1300, maxTimeToRun: 60);
}
[Test]
public async Task AddingImageConverterWorks()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab();
testRunner.AddItemToBed("Primitives Row Item Collection", "Row Item Image Converter");
var view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
testRunner.Assert(() => scene.Children.Count == 1, $"Should have 1 scene item after first AddToBed")
.Assert(() => scene.Descendants().Where(i => i is ImageObject3D).Any(), $"Should have 1 scene item after first AddToBed");
return Task.CompletedTask;
}, overrideWidth: 1300, maxTimeToRun: 60);
}
[Test]
public static async Task ControlClickInDesignTreeView()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab();
var parts = new[]
{
"Row Item Cube",
"Row Item Half Cylinder",
"Row Item Half Wedge",
"Row Item Pyramid"
};
testRunner.AddPrimitivePartsToBed(parts, multiSelect: false);
var view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
var designTree = testRunner.GetWidgetByName("DesignTree", out _, 3) as TreeView;
Assert.AreEqual(scene.Children.Count, FetchTreeNodes().Count, "Scene part count should equal tree node count");
// Open up some room in the design tree view panel for adding group and selection nodes.
var splitter = designTree.Parents<Splitter>().First();
var splitterBar = splitter.Children.Where(child => child.GetType().Name == "SplitterBar").First();
var treeNodes = FetchTreeNodes();
var cubeNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Cube").Single();
var expandBy = cubeNode.Size.Y * 4d;
testRunner.DragWidget(splitterBar, new Point2D(0, expandBy)).Drop();
//===========================================================================================//
// Verify control-click isn't broken in library view.
var moreParts = new[]
{
"Row Item Sphere",
"Row Item Wedge"
};
testRunner.AddPrimitivePartsToBed(moreParts, multiSelect: true);
var partCount = parts.Length + moreParts.Length;
Assert.IsTrue(scene.Children.Any(child => child is SelectionGroupObject3D), "Scene should have a selection child");
treeNodes = FetchTreeNodes();
Assert.IsFalse(treeNodes.Where(node => node.Tag is SelectionGroupObject3D).Any());
Assert.AreEqual(treeNodes.Count, partCount, "Design tree should show all parts");
Assert.AreEqual(
scene.Children.Sum(child =>
{
if (child is SelectionGroupObject3D selection)
{
return selection.Children.Count;
}
return 1;
}),
treeNodes.Count,
"Number of parts in scene should equal number of nodes in design view");
//===========================================================================================//
// Verify rectangle drag select on bed creates a selection group in scene only.
//
// Rotate bed to top-down view so it's easier to select parts.
var top = Matrix4X4.LookAt(Vector3.Zero, new Vector3(0, 0, -1), new Vector3(0, 1, 0));
view3D.TrackballTumbleWidget.AnimateRotation(top);
testRunner.Delay()
.ClickByName("Pyramid")
.Delay()
.RectangleSelectParts(view3D.Object3DControlLayer, new[] { "Cube", "Pyramid" })
.Delay();
Assert.AreEqual(partCount - 3, scene.Children.Count, "Scene should have {0} children after drag rectangle select", partCount - 3);
Assert.IsTrue(scene.Children.Any(child => child is SelectionGroupObject3D), "Scene should have a selection child after drag rectangle select");
Assert.AreEqual(4, scene.SelectedItem.Children.Count, "4 parts should be selected");
Assert.IsTrue(
new HashSet<string>(scene.SelectedItem.Children.Select(child => child.Name)).SetEquals(new[] { "Cube", "Half Wedge", "Half Cylinder", "Pyramid" }),
"Cube, Half Cylinder, Half Wedge, Pyramid should be selected");
treeNodes = FetchTreeNodes();
Assert.IsFalse(treeNodes.Where(node => node.Tag is SelectionGroupObject3D).Any());
Assert.AreEqual(
scene.Children.Sum(child =>
{
if (child is SelectionGroupObject3D selection)
{
return selection.Children.Count;
}
return 1;
}),
treeNodes.Count,
"Number of parts in scene should equal number of nodes in design view afte drag rectangle select");
//===========================================================================================//
// Verify shift-clicking on parts on bed creates a selection group.
testRunner
.ClickByName("Sphere")
.ClickByName("Half Cylinder")
.PressModifierKeys(AutomationRunner.ModifierKeys.Shift)
.ClickByName("Pyramid")
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Shift);
Assert.AreEqual(partCount - 1, scene.Children.Count, "Should have {0} children after selection", partCount - 1);
Assert.IsTrue(scene.Children.Any(child => child is SelectionGroupObject3D), "Selection group should be child of scene");
Assert.IsFalse(scene.Children.Any(child => child.Name == "Half Cylinder" || child.Name == "Pyramid"), "Half Cylinder and Pyramid should be removed as direct children of scene");
Assert.IsNull(designTree.SelectedNode, "Design tree shouldn't have a selected node when multiple parts are selected");
//===========================================================================================//
// Verify grouping parts creates a group.
testRunner.ClickByName("Group Button");
Assert.AreEqual(partCount - 1, scene.Children.Count, "Should have {0} parts after group", partCount - 1);
Assert.IsInstanceOf<GroupObject3D>(scene.SelectedItem, "Scene selection should be group");
Assert.IsInstanceOf<GroupObject3D>(designTree.SelectedNode.Tag, "Group should be selected in design tree");
Assert.AreSame(scene.SelectedItem, designTree.SelectedNode.Tag, "Same group object should be selected in scene and design tree");
treeNodes = FetchTreeNodes();
Assert.AreEqual(scene.Children.Count, treeNodes.Count, "Scene part count should equal tree node count after group");
Assert.IsTrue(treeNodes.Any(node => node.Tag is GroupObject3D), "Design tree should have node for group");
Assert.AreSame(designTree.SelectedNode.Tag, treeNodes.Single(node => node.Tag is GroupObject3D).Tag, "Selected node in design tree should be group node");
var groupNode = treeNodes.Where(node => node.Tag is GroupObject3D).Single();
Assert.AreEqual(2, groupNode.Nodes.Count, "Group should have 2 parts");
Assert.IsTrue(
new HashSet<string>(groupNode.Nodes.Select(node => ((IObject3D)node.Tag).Name)).SetEquals(new[] {"Half Cylinder", "Pyramid"}),
"Half Cylinder and Pyramind should be grouped");
var singleItemNodes = treeNodes
.Where(node => !(node.Tag is GroupObject3D))
.Where(node => !(node.Tag is SelectionGroupObject3D))
.ToList();
var singleItemNames = new HashSet<string>(singleItemNodes.Select(item => ((IObject3D)item.Tag).Name));
Assert.AreEqual(partCount - 2, singleItemNodes.Count, "There should be {0} single item nodes in the design tree", partCount - 2);
Assert.IsTrue(singleItemNames.SetEquals(new[] {"Cube", "Half Wedge", "Sphere", "Wedge"}), "Cube, Half Wedge, Sphere, Wedge should be single items");
//===========================================================================================//
// Verify using the design tree to create a selection group.
var halfWedgeNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Half Wedge").Single();
var sphereNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Sphere").Single();
testRunner.ClickWidget(halfWedgeNode)
.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(sphereNode)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
Assert.AreEqual(partCount - 2, scene.Children.Count, "Should have {0} parts after selection", partCount - 2);
Assert.IsNull(designTree.SelectedNode, "Design tree shouldn't have a selected node after creating selection in design tree");
//===========================================================================================//
// Verify control-clicking a part in the group does not get added to the selection group. Only top-level nodes can be
// selected.
treeNodes = FetchTreeNodes();
groupNode = treeNodes.Where(node => node.Tag is GroupObject3D).Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(groupNode.Nodes.Last())
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
Assert.AreEqual(
scene.Children.Sum(child =>
{
if (child is SelectionGroupObject3D selection)
{
return selection.Children.Count;
}
return 1;
}),
treeNodes.Count,
"Scene part count should equal design tree node count after control-click on group child");
Assert.IsInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Selection shouldn't change after control-click on group child");
Assert.AreEqual(2, scene.SelectedItem.Children.Count, "Selection should have 2 parts after control-click on group child");
//===========================================================================================//
// Verify adding group to selection.
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(groupNode.TitleBar)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
Assert.AreEqual(partCount - 3, scene.Children.Count, "Scene should have {0} children after control-clicking group", partCount - 3);
Assert.IsInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Selected item should be a selection group after control-clicking on group");
Assert.AreEqual(3, scene.SelectedItem.Children.Count, "Selection should have 3 items after control-clicking on group");
Assert.IsTrue(
new HashSet<string>(scene.SelectedItem.Children.Select(child => child.Name)).SetEquals(new[] {"Half Wedge", "Sphere", "Group"}),
"Selection should have Group, Half Wedge, Sphere");
//===========================================================================================//
// Verify control-clicking on a part in the selection removes it from the selection.
treeNodes = FetchTreeNodes();
halfWedgeNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Half Wedge").Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(halfWedgeNode)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
Assert.IsInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Selection group should exist after removing a child");
Assert.AreEqual(2, scene.SelectedItem.Children.Count, "Selection should have 2 parts after removing a child");
Assert.IsTrue(
new HashSet<string>(scene.SelectedItem.Children.Select(child => child.Name)).SetEquals(new[] {"Group", "Sphere"}),
"Group and Sphere should be in selection after removing a child");
//===========================================================================================//
// Verify control-clicking on second-to-last part in the selection removes it from the selection
// and destroys selection group.
treeNodes = FetchTreeNodes();
groupNode = treeNodes.Where(node => node.Tag is GroupObject3D).Single();
sphereNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Sphere").Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(sphereNode)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
treeNodes = FetchTreeNodes();
Assert.AreEqual(scene.Children.Count, treeNodes.Count, "Scene part count should equal design tree node count after removing penultimate child");
Assert.IsNotInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Selection group shouldn't exist after removing penultimate child");
Assert.AreSame(groupNode.Tag, scene.SelectedItem, "Selection should be group after removing penultimate child");
//===========================================================================================//
// Verify control-clicking on a part in the group that's part of the selection doesn't change the selection.
halfWedgeNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Half Wedge").Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(halfWedgeNode)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
treeNodes = FetchTreeNodes();
sphereNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Sphere").Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(sphereNode)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
treeNodes = FetchTreeNodes();
groupNode = treeNodes.Where(node => node.Tag is GroupObject3D).Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(groupNode.Nodes.Last())
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
Assert.IsInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Selection shouldn't change after control-click on selection group child");
Assert.AreEqual(3, scene.SelectedItem.Children.Count, "Selection should have 3 parts after control-click on selection group child");
//===========================================================================================//
// Verify clicking on a top-level node that's not in the selection group unselects all the parts in the group
// and selects the part associated with the clicked node.
treeNodes = FetchTreeNodes();
var wedgeNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Wedge").Single();
testRunner.ClickWidget(wedgeNode);
Assert.AreEqual(partCount - 1, scene.Children.Count, "Should be {0} parts in the scene after selecting wedge", partCount - 1);
Assert.AreSame(scene.SelectedItem, wedgeNode.Tag, "Wedge should be selected");
Assert.IsFalse(scene.Children.Any(child => child is SelectionGroupObject3D), "Selection group should go away when another part is selected");
Assert.AreSame(scene.SelectedItem, designTree.SelectedNode.Tag, "The same part should be selected in the scene and design tree");
treeNodes = FetchTreeNodes();
wedgeNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Wedge").Single();
Assert.AreSame(designTree.SelectedNode, wedgeNode, "Wedge node should be selected in design tree");
Assert.IsFalse(treeNodes.Any(node => node.Tag is SelectionGroupObject3D), "Selection group shouldn't exist in design tree after selecting wedge");
//===========================================================================================//
// Verify that shift-clicking a part on the bed makes a selection group with a part that's been selected through
// the design tree.
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Shift)
.ClickByName("Half Wedge")
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Shift);
Assert.AreEqual(partCount - 2, scene.Children.Count, "Scene should have {0} children after selecting half wedge", partCount - 2);
Assert.IsNull(designTree.SelectedNode, "Selected node in design tree should be null after selecting half wedge");
Assert.IsInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Should have a selection group after selecting half wedge");
Assert.IsTrue(
new HashSet<string>(scene.SelectedItem.Children.Select(child => child.Name)).SetEquals(new [] {"Wedge", "Half Wedge"}),
"Half Wedge and Wedge should be in selection");
//===========================================================================================//
// Verify that control-click on a top-level part adds to an existing selection.
treeNodes = FetchTreeNodes();
sphereNode = treeNodes.Where(node => ((IObject3D)node.Tag).Name == "Sphere").Single();
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control)
.ClickWidget(sphereNode)
.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
Assert.AreEqual(partCount - 3, scene.Children.Count, "Scene should have {0} children after selecting sphere", partCount - 3);
Assert.IsInstanceOf<SelectionGroupObject3D>(scene.SelectedItem, "Selection in scene should be selection group after adding sphere");
Assert.IsTrue(
new HashSet<string>(scene.SelectedItem.Children.Select(child => child.Name)).SetEquals(new [] {"Wedge", "Half Wedge", "Sphere"}),
"Half Wedge, Sphere, Wedge should be in selection");
//===========================================================================================//
// Done
return Task.CompletedTask;
// The nodes in the design tree are regenerated after certain events and must
// be fetched anew.
List<TreeNode> FetchTreeNodes() =>
designTree.Children
.Where(child => child is ScrollingArea)
.First()
.Children
.Where(child => child is FlowLayoutWidget)
.First()
.Children
.Select(child => (TreeNode)child)
.ToList();
}, overrideWidth: 1300, maxTimeToRun: 110);
}
[Test]
public async Task DesignTabFileOperations()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab(false);
// Get View3DWidget
var view3D = testRunner.GetWidgetByName("View3DWidget", out SystemWindow systemWindow, 3) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
var tempFilaname = "Temp Test Save.mcx";
var tempFullPath = Path.Combine(ApplicationDataStorage.Instance.DownloadsDirectory, tempFilaname);
// delete the temp file if it exists in the Downloads folder
void DeleteTempFile()
{
if (File.Exists(tempFullPath))
{
File.Delete(tempFullPath);
}
}
DeleteTempFile();
testRunner.Assert(() => scene.Children.Count == 1, "Should have 1 part (the phil)")
// Make sure the tab is named 'New Design'
.Assert(() => systemWindow.GetVisibleWigetWithText("New Design") != null, "Must have New Design")
// add a new part to the bed
.AddItemToBed()
// Click the save button
.ClickByName("Save")
// Cancle the save as
.ClickByName("Cancel Wizard Button")
// Make sure the tab is named 'New Design'
.Assert(() => systemWindow.GetVisibleWigetWithText("New Design") != null, "Have a new design tab")
// Click the close tab button
.ClickByName("Close Tab Button")
// Select Cancel
.ClickByName("Cancel Button")
// Make sure the tab is named 'New Design'
.Assert(() => systemWindow.GetVisibleWigetWithText("New Design") != null, "Still have design tab")
// Click the close tab button
.ClickByName("Close Tab Button")
// Select 'Save'
.ClickByName("Yes Button")
// Cancel the 'Save As'
.ClickByName("Cancel Wizard Button")
// Make sure the window is still open and the tab is named 'New Design'
.Assert(() => systemWindow.GetVisibleWigetWithText("New Design") != null, "still have desin tab")
// Click the save button
.ClickByName("Save")
// Save a temp file to the downloads folder
.DoubleClickByName("Computer Row Item Collection")
.DoubleClickByName("Downloads Row Item Collection")
.ClickByName("Design Name Edit Field")
.Type(tempFilaname)
.ClickByName("Accept Button")
// Verify it is there
.Assert(() => File.Exists(tempFullPath), "Must save the file")
// And that the tab got the name
.Assert(() => systemWindow.GetVisibleWigetWithText(tempFilaname) != null, "Tab was renamed")
// and the tooltip is right
.Assert(() => systemWindow.GetVisibleWigetWithText(tempFilaname).ToolTipText == tempFullPath, "Correct tool tip name")
// Add a part to the bed
.AddItemToBed()
// Click the close tab button (we have an edit so it should show the save request)
.ClickByName("Close Tab Button")
// Click the 'Cancel'
.ClickByName("Cancel Button")
// Click the 'Save' button
.ClickByName("Save")
// Click the close button (now we have no edit it should cancel without request)
.ClickByName("Close Tab Button");
// Verify the tab closes without requesting save
testRunner.Assert(() => systemWindow.GetVisibleWigetWithText(tempFilaname) == null, "The tab should have closed");
// delete the temp file if it exists in the Downloads folder
DeleteTempFile();
return Task.CompletedTask;
}, maxTimeToRun: 60);
}
[Test]
public async Task GroupAndUngroup()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab();
testRunner.AddItemToBed();
// Get View3DWidget and count Scene.Children before Copy button is clicked
View3DWidget view3D = testRunner.GetWidgetByName("View3DWidget", out _, 3) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
// Assert expected start count
Assert.AreEqual(1, scene.Children.Count, "Should have one part before copy");
// Select scene object
testRunner.Select3DPart("Calibration - Box.stl");
for (int i = 2; i <= 6; i++)
{
testRunner.ClickByName("Duplicate Button")
.Assert(() => scene.Children.Count == i, $"Should have {i} parts after copy");
}
// Get MeshGroupCount before Group is clicked
Assert.AreEqual(6, scene.Children.Count, "Scene should have 6 parts after copy loop");
// Duplicate button moved to new container - move focus back to View3DWidget so CTRL-A below is seen by expected control
testRunner.Select3DPart("Calibration - Box.stl")
// select all
.Type("^a")
.ClickByName("Group Button")
.Assert(() => scene.Children.Count == 1, $"Should have 1 parts after group");
testRunner.ClickByName("Ungroup Button")
.Assert(() => scene.Children.Count == 6, $"Should have 6 parts after ungroup");
return Task.CompletedTask;
}, overrideWidth: 1300);
}
[Test]
public async Task RemoveButtonRemovesParts()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.OpenPartTab();
testRunner.AddItemToBed();
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
var scene = view3D.Object3DControlLayer.Scene;
testRunner.Select3DPart("Calibration - Box.stl");
Assert.AreEqual(1, scene.Children.Count, "There should be 1 part on the bed after AddDefaultFileToBedplate()");
// Add 5 items
for (int i = 0; i <= 4; i++)
{
testRunner.ClickByName("Duplicate Button")
.Delay(.5);
}
Assert.AreEqual(6, scene.Children.Count, "There should be 6 parts on the bed after the copy loop");
// Remove an item
testRunner.ClickByName("Remove Button");
// Confirm
Assert.AreEqual(5, scene.Children.Count, "There should be 5 parts on the bed after remove");
return Task.CompletedTask;
});
}
[Test]
public async Task SaveAsToQueue()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.AddAndSelectPrinter();
testRunner.AddItemToBed();
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
testRunner.Select3DPart("Calibration - Box.stl");
int expectedCount = QueueData.Instance.ItemCount + 1;
testRunner.SaveBedplateToFolder("Test PartA.mcx", "Queue Row Item Collection")
.NavigateToLibraryHome()
.NavigateToFolder("Queue Row Item Collection");
Assert.IsTrue(testRunner.WaitForName("Row Item Test PartA.mcx"), "The part we added should be in the library");
Assert.AreEqual(expectedCount, QueueData.Instance.ItemCount, "Queue count should increase by one after Save operation");
return Task.CompletedTask;
});
}
[Test]
public async Task SaveAsToLocalLibrary()
{
await MatterControlUtilities.RunTest((testRunner) =>
{
testRunner.AddAndSelectPrinter();
testRunner.AddItemToBed();
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
testRunner.Select3DPart("Calibration - Box.stl");
int expectedCount = QueueData.Instance.ItemCount + 1;
testRunner.SaveBedplateToFolder("Test PartB", "Local Library Row Item Collection")
.NavigateToLibraryHome()
.NavigateToFolder("Local Library Row Item Collection");
Assert.IsTrue(testRunner.WaitForName("Row Item Test PartB"), "The part we added should be in the library");
return Task.CompletedTask;
});
}
}
public static class WidgetExtensions
{
/// <summary>
/// Search the widget stack for a widget that is both visible on screen and has it's text set to the visibleText string
/// </summary>
/// <param name="widget">The root widget to search</param>
/// <param name="">the name to search for</param>
/// <returns></returns>
public static GuiWidget GetVisibleWigetWithText(this GuiWidget widget, string visibleText)
{
if (widget.ActuallyVisibleOnScreen())
{
if (widget.Text == visibleText)
{
return widget;
}
foreach(var child in widget.Children)
{
var childWithText = GetVisibleWigetWithText(child, visibleText);
if (childWithText != null)
{
return childWithText;
}
}
}
return null;
}
}
}