Create automation test for control-click in design tree view
This commit is contained in:
parent
37751ebeb8
commit
5734368188
3 changed files with 432 additions and 19 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -116,4 +116,7 @@ Backup*/
|
|||
UpgradeLog*.XML
|
||||
MatterControl.userprefs
|
||||
|
||||
.vs/
|
||||
.vs/
|
||||
|
||||
# JetBrains Rider user configuration directory
|
||||
/.idea/
|
||||
|
|
|
|||
|
|
@ -27,13 +27,21 @@ 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.Operations;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MatterControl.PrintQueue;
|
||||
using MatterHackers.VectorMath;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace MatterHackers.MatterControl.Tests.Automation
|
||||
|
|
@ -101,6 +109,296 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
}, 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 DesignTabFileOpperations()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,9 +39,11 @@ using MatterHackers.Agg;
|
|||
using MatterHackers.Agg.Image;
|
||||
using MatterHackers.Agg.Platform;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.GuiAutomation;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using MatterHackers.MatterControl.DataStorage;
|
||||
using MatterHackers.MatterControl.DesignTools.Operations;
|
||||
using MatterHackers.MatterControl.Library;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MatterControl.PrinterCommunication;
|
||||
|
|
@ -124,10 +126,14 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
const string containerName = "Primitives Row Item Collection";
|
||||
testRunner.NavigateToFolder(containerName);
|
||||
|
||||
if (multiSelect)
|
||||
{
|
||||
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control);
|
||||
}
|
||||
|
||||
var partCount = 0;
|
||||
foreach (var partName in partNames)
|
||||
{
|
||||
Keyboard.SetKeyDownState(Keys.ControlKey, multiSelect);
|
||||
foreach (var result in testRunner.GetWidgetsByName(partName))
|
||||
{
|
||||
// Opening the primitive parts library folder causes a second set of primitive part widgets to be created.
|
||||
|
|
@ -144,34 +150,35 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
}
|
||||
if (!partWidget.IsSelected)
|
||||
{
|
||||
testRunner.ClickWidget(partWidget);
|
||||
if (multiSelect)
|
||||
{
|
||||
testRunner.ClickWidget(partWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
testRunner.RightClickWidget(partWidget)
|
||||
.ClickByName("Add to Bed Menu Item");
|
||||
}
|
||||
}
|
||||
partCount += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (multiSelect)
|
||||
{
|
||||
// Release control key so additional operations work normally.
|
||||
Keyboard.SetKeyDownState(Keys.ControlKey, false);
|
||||
testRunner.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control)
|
||||
.ClickByName("Print Library Overflow Menu")
|
||||
.ClickByName("Add to Bed Menu Item");
|
||||
}
|
||||
|
||||
testRunner.ClickByName("Print Library Overflow Menu");
|
||||
|
||||
var view3D = testRunner.GetWidgetByName("View3DWidget", out _) as View3DWidget;
|
||||
var scene = view3D.Object3DControlLayer.Scene;
|
||||
var preAddCount = scene.Children.Count;
|
||||
var postAddCount = preAddCount + (multiSelect ? 1 : partCount);
|
||||
|
||||
testRunner.ClickByName("Add to Bed Menu Item")
|
||||
// wait for the objects to be added
|
||||
.WaitFor(() => scene.Children.Count == postAddCount);
|
||||
// wait for the objects to be done loading
|
||||
var insertionGroup = scene.Children.LastOrDefault() as InsertionGroupObject3D;
|
||||
if (insertionGroup != null)
|
||||
{
|
||||
testRunner.WaitFor(() => scene.Children.LastOrDefault() as InsertionGroupObject3D != null, 10);
|
||||
}
|
||||
// wait for the objects to be added
|
||||
testRunner.WaitFor(() => scene.Children.Count == postAddCount, 1);
|
||||
|
||||
return testRunner;
|
||||
}
|
||||
|
|
@ -950,6 +957,8 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
}
|
||||
|
||||
UserSettings.Instance.set(UserSettingsKey.ThumbnailRenderingMode, "orthographic");
|
||||
// The EULA popup throws off the tests on Linux.
|
||||
UserSettings.Instance.set(UserSettingsKey.SoftwareLicenseAccepted, "true");
|
||||
// GL.HardwareAvailable = false;
|
||||
|
||||
var config = TestAutomationConfig.Load();
|
||||
|
|
@ -1483,13 +1492,116 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
public static void SelectListItems(this AutomationRunner testRunner, params string[] widgetNames)
|
||||
{
|
||||
// Control click all items
|
||||
Keyboard.SetKeyDownState(Keys.ControlKey, down: true);
|
||||
testRunner.PressModifierKeys(AutomationRunner.ModifierKeys.Control);
|
||||
foreach (var widgetName in widgetNames)
|
||||
{
|
||||
testRunner.ClickByName(widgetName);
|
||||
}
|
||||
|
||||
Keyboard.SetKeyDownState(Keys.ControlKey, down: false);
|
||||
testRunner.ReleaseModifierKeys(AutomationRunner.ModifierKeys.Control);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses the drag rectangle on the bed to select parts. Assumes the bed has been rotated to a
|
||||
/// bird's eye view (top down). That makes it easier to select the correct parts because the
|
||||
/// drag rectangle will be parallel to the XY plane.
|
||||
/// </summary>
|
||||
/// <param name="testRunner">The AutomationRunner in use</param>
|
||||
/// <param name="controlLayer">Object control layer from a View3DWidget</param>
|
||||
/// <param name="partNames">Names of the parts to select</param>
|
||||
/// <returns>The AutomationRunner</returns>
|
||||
public static AutomationRunner RectangleSelectParts(this AutomationRunner testRunner, Object3DControlsLayer controlLayer, IEnumerable<string> partNames)
|
||||
{
|
||||
var topWindow = controlLayer.Parents<SystemWindow>().First();
|
||||
var widgets = partNames
|
||||
.Select(name => ResolveName(controlLayer.Scene.Children, name))
|
||||
.Where(x => x.Ok)
|
||||
.Select(x =>
|
||||
{
|
||||
var widget = testRunner.GetWidgetByName(x.Name, out var containingWindow, 1);
|
||||
return new
|
||||
{
|
||||
Widget = widget ?? controlLayer,
|
||||
ContainingWindow = widget != null ? containingWindow : topWindow,
|
||||
x.Bounds
|
||||
};
|
||||
})
|
||||
.ToList();
|
||||
if (!widgets.Any())
|
||||
{
|
||||
return testRunner;
|
||||
}
|
||||
|
||||
var minPosition = widgets.Aggregate((double.MaxValue, double.MaxValue), (acc, wi) =>
|
||||
{
|
||||
var bounds = wi.Widget.TransformToParentSpace(wi.ContainingWindow, wi.Bounds);
|
||||
var x = bounds.Left - 1;
|
||||
var y = bounds.Bottom - 1;
|
||||
return (x < acc.Item1 ? x : acc.Item1, y < acc.Item2 ? y : acc.Item2);
|
||||
});
|
||||
var maxPosition = widgets.Aggregate((0d, 0d), (acc, wi) =>
|
||||
{
|
||||
var bounds = wi.Widget.TransformToParentSpace(wi.ContainingWindow, wi.Bounds);
|
||||
var x = bounds.Right + 1;
|
||||
var y = bounds.Top + 1;
|
||||
return (x > acc.Item1 ? x : acc.Item1, y > acc.Item2 ? y : acc.Item2);
|
||||
});
|
||||
|
||||
var systemWindow = widgets.First().ContainingWindow;
|
||||
testRunner.SetMouseCursorPosition(systemWindow, (int)minPosition.Item1, (int)minPosition.Item2);
|
||||
testRunner.DragToPosition(systemWindow, (int)maxPosition.Item1, (int)maxPosition.Item2).Drop();
|
||||
|
||||
return testRunner;
|
||||
|
||||
RectangleDouble GetBoundingBox(IObject3D part)
|
||||
{
|
||||
var screenBoundsOfObject3D = RectangleDouble.ZeroIntersection;
|
||||
var bounds = part.GetBVHData().GetAxisAlignedBoundingBox();
|
||||
|
||||
for (var i = 0; i < 4; i += 1)
|
||||
{
|
||||
screenBoundsOfObject3D.ExpandToInclude(controlLayer.World.GetScreenPosition(bounds.GetTopCorner(i)));
|
||||
screenBoundsOfObject3D.ExpandToInclude(controlLayer.World.GetScreenPosition(bounds.GetBottomCorner(i)));
|
||||
}
|
||||
|
||||
return screenBoundsOfObject3D;
|
||||
}
|
||||
|
||||
(bool Ok, string Name, RectangleDouble Bounds)
|
||||
ResolveName(IEnumerable<IObject3D> parts, string name)
|
||||
{
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (part.Name == name)
|
||||
{
|
||||
return (true, name, GetBoundingBox(part));
|
||||
}
|
||||
|
||||
if (part is GroupObject3D group)
|
||||
{
|
||||
var (ok, _, bounds) = ResolveName(group.Children, name);
|
||||
if (ok)
|
||||
{
|
||||
// WARNING the position of a part changes when it's added to a group.
|
||||
// Not sure if there's some sort of offset that needs to be applied or
|
||||
// if this is a bug. It is restored to its correct position when the
|
||||
// part is ungrouped.
|
||||
return (true, name, bounds);
|
||||
}
|
||||
}
|
||||
|
||||
if (part is SelectionGroupObject3D selection)
|
||||
{
|
||||
var (ok, _, bounds) = ResolveName(selection.Children, name);
|
||||
if (ok)
|
||||
{
|
||||
return (true, name, bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false, null, RectangleDouble.ZeroIntersection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1563,4 +1675,4 @@ namespace MatterHackers.MatterControl.Tests.Automation
|
|||
File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue