From 2d769c187bdd019bc802b444993403b22f26651e Mon Sep 17 00:00:00 2001 From: larsbrubaker Date: Sun, 16 Aug 2015 16:01:42 -0700 Subject: [PATCH] Putting in support for running skuli type tests. --- ApplicationView/CompactSlidePanel.cs | 1 + MatterControl.csproj | 4 + MatterControl.sln | 34 +++++ MatterControlApplication.cs | 17 ++- Submodules/agg-sharp | 2 +- TestRunner/TestRunner.cs | 189 +++++++++++++++++++++++++++ TestRunner/TestRunner.csproj | 163 +++++++++++++++++++++++ TestRunner/app.config | 11 ++ 8 files changed, 417 insertions(+), 4 deletions(-) create mode 100644 TestRunner/TestRunner.cs create mode 100644 TestRunner/TestRunner.csproj create mode 100644 TestRunner/app.config diff --git a/ApplicationView/CompactSlidePanel.cs b/ApplicationView/CompactSlidePanel.cs index 66b2baec4..e18b6af48 100644 --- a/ApplicationView/CompactSlidePanel.cs +++ b/ApplicationView/CompactSlidePanel.cs @@ -84,6 +84,7 @@ namespace MatterHackers.MatterControl advancedControlsButtonFactory.invertImageLocation = true; Button advancedControlsLinkButton = advancedControlsButtonFactory.Generate(LocalizedString.Get("Settings\n& Controls"), "icon_arrow_right_32x32.png"); + advancedControlsLinkButton.Name = "SettingsAndControls"; advancedControlsLinkButton.ToolTipText = "Switch to Settings, Controls and Options".Localize(); advancedControlsLinkButton.Margin = new BorderDouble(right: 3); advancedControlsLinkButton.VAnchor = VAnchor.ParentBottom; diff --git a/MatterControl.csproj b/MatterControl.csproj index 18e9c332b..9d7bb140b 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -519,5 +519,9 @@ {990A9AD3-B6A4-407B-9DFC-9C722AF7C9B9} InfInstaller + + {9d193b5c-bef4-44b2-ad6d-597b7a2c52c5} + TestRunner + \ No newline at end of file diff --git a/MatterControl.sln b/MatterControl.sln index e755c1bb8..aaf3b8232 100644 --- a/MatterControl.sln +++ b/MatterControl.sln @@ -120,6 +120,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X3GDriver", "..\X3GDriver\X EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Nat", "..\CloudServicesPlugin\Mono.Nat\Mono.Nat.csproj", "{F5D74163-145F-47BF-83DC-D0E07249C6CA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestRunner", "TestRunner\TestRunner.csproj", "{9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1073,6 +1075,38 @@ Global {F5D74163-145F-47BF-83DC-D0E07249C6CA}.Release64|x64.ActiveCfg = Release|x64 {F5D74163-145F-47BF-83DC-D0E07249C6CA}.Release64|x64.Build.0 = Release|x64 {F5D74163-145F-47BF-83DC-D0E07249C6CA}.Release64|x86.ActiveCfg = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x64.ActiveCfg = Debug|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x64.Build.0 = Debug|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug|x86.Build.0 = Debug|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Any CPU.ActiveCfg = Debug64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Any CPU.Build.0 = Debug64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Mixed Platforms.ActiveCfg = Debug64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|Mixed Platforms.Build.0 = Debug64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x64.ActiveCfg = Debug64|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x64.Build.0 = Debug64|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x86.ActiveCfg = Debug64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Debug64|x86.Build.0 = Debug64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Any CPU.Build.0 = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x64.ActiveCfg = Release|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x64.Build.0 = Release|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x86.ActiveCfg = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release|x86.Build.0 = Release|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Any CPU.ActiveCfg = Release64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Any CPU.Build.0 = Release64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Mixed Platforms.ActiveCfg = Release64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|Mixed Platforms.Build.0 = Release64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x64.ActiveCfg = Release64|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x64.Build.0 = Release64|x64 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x86.ActiveCfg = Release64|Any CPU + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5}.Release64|x86.Build.0 = Release64|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MatterControlApplication.cs b/MatterControlApplication.cs index 4094ee689..fb9a1878c 100644 --- a/MatterControlApplication.cs +++ b/MatterControlApplication.cs @@ -39,6 +39,7 @@ using MatterHackers.MatterControl.SettingsManagement; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.PolygonMesh.Processors; using MatterHackers.RenderOpenGl.OpenGl; +using MatterHackers.TestRunner; using MatterHackers.VectorMath; using Mindscape.Raygun4Net; using System; @@ -48,12 +49,13 @@ using System.Globalization; using System.IO; using System.Text.RegularExpressions; using System.Threading; +using System.Threading.Tasks; namespace MatterHackers.MatterControl { - public class MatterControlApplication : SystemWindow + public class MatterControlApplication : SystemWindow { - public bool RestartOnClose = false; + public bool RestartOnClose = false; private static readonly Vector2 minSize = new Vector2(600, 600); private static MatterControlApplication instance; private string[] commandLineArgs = null; @@ -531,6 +533,7 @@ namespace MatterHackers.MatterControl if (firstDraw) { + Task.Run((Action)ButtonClickTest); UiThread.RunOnIdle(DoAutoConnectIfRequired); firstDraw = false; @@ -553,7 +556,15 @@ namespace MatterHackers.MatterControl //msGraph.Draw(MatterHackers.Agg.Transform.Affine.NewIdentity(), graphics2D); } - public override void OnMouseMove(MouseEventArgs mouseEvent) + private void ButtonClickTest() + { + TestFramework test = new TestFramework("C:/TestImages"); + ImageIO.SaveImageData("test.png", test.GetCurrentScreen()); + test.Wait(2); + test.ClickByName("SettingsAndControls"); + } + + public override void OnMouseMove(MouseEventArgs mouseEvent) { if (GuiWidget.DebugBoundsUnderMouse) { diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 8d9f6e03a..eb55baa0c 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 8d9f6e03a29a901ac674e6f3e3e3dd2e8aeb8f13 +Subproject commit eb55baa0c70604672943e7b6dbfa5ebb5d0a533a diff --git a/TestRunner/TestRunner.cs b/TestRunner/TestRunner.cs new file mode 100644 index 000000000..5e1347254 --- /dev/null +++ b/TestRunner/TestRunner.cs @@ -0,0 +1,189 @@ +/* +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. +*/ + +using MatterHackers.Agg; +using MatterHackers.Agg.Image; +using MatterHackers.Agg.UI; +using MatterHackers.VectorMath; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace MatterHackers.TestRunner +{ + public class TestFramework + { + // P/Invoke declarations + [DllImport("gdi32.dll")] + static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int + wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop); + [DllImport("user32.dll")] + static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc); + [DllImport("gdi32.dll")] + static extern IntPtr DeleteDC(IntPtr hDc); + [DllImport("gdi32.dll")] + static extern IntPtr DeleteObject(IntPtr hDc); + [DllImport("gdi32.dll")] + static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); + [DllImport("gdi32.dll")] + static extern IntPtr CreateCompatibleDC(IntPtr hdc); + [DllImport("gdi32.dll")] + static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp); + [DllImport("user32.dll")] + public static extern IntPtr GetDesktopWindow(); + [DllImport("user32.dll")] + public static extern IntPtr GetWindowDC(IntPtr ptr); + + string imageDirectory; + + public TestFramework(string imageDirectory) + { + this.imageDirectory = imageDirectory; + } + + public bool ClickByName(string widgetName, int xOffset = 0, int yOffset = 0, double upDelaySeconds = .2) + { + foreach (SystemWindow window in SystemWindow.OpenWindows) + { + GuiWidget widgetToClick = window.FindNamedChildRecursive(widgetName); + if (widgetToClick != null) + { + RectangleDouble childBounds = widgetToClick.TransformToParentSpace(window, widgetToClick.LocalBounds); + UiThread.RunOnIdle(() => + window.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, + childBounds.Left + xOffset, childBounds.Bottom + yOffset, + 0))); + Wait(upDelaySeconds); + UiThread.RunOnIdle(() => + window.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 0, + childBounds.Left + xOffset, childBounds.Bottom + yOffset, + 0))); + return true; + } + } + return false; + } + + public bool NameExists(string widgetName) + { + foreach (SystemWindow window in SystemWindow.OpenWindows) + { + GuiWidget widgetToClick = window.FindNamedChildRecursive(widgetName); + if (widgetToClick != null) + { + return true; + } + } + + return false; + } + + public ImageBuffer GetCurrentScreen() + { + ImageBuffer screenCapture = new ImageBuffer(); + + Size sz = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Size; + IntPtr hDesk = GetDesktopWindow(); + IntPtr hSrce = GetWindowDC(hDesk); + IntPtr hDest = CreateCompatibleDC(hSrce); + IntPtr hBmp = CreateCompatibleBitmap(hSrce, sz.Width, sz.Height); + IntPtr hOldBmp = SelectObject(hDest, hBmp); + bool b = BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); + Bitmap bmpScreenCapture = Bitmap.FromHbitmap(hBmp); + SelectObject(hDest, hOldBmp); + DeleteObject(hBmp); + DeleteDC(hDest); + ReleaseDC(hDesk, hSrce); + + //bmpScreenCapture.Save("bitmapsave.png"); + + screenCapture = new ImageBuffer(bmpScreenCapture.Width, bmpScreenCapture.Height, 32, new BlenderBGRA()); + BitmapData bitmapData = bmpScreenCapture.LockBits(new Rectangle(0, 0, bmpScreenCapture.Width, bmpScreenCapture.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bmpScreenCapture.PixelFormat); + + int offset; + byte[] buffer = screenCapture.GetBuffer(out offset); + int bitmapDataStride = bitmapData.Stride; + int backBufferStrideInBytes = screenCapture.StrideInBytes(); + int backBufferHeight = screenCapture.Height; + int backBufferHeightMinusOne = backBufferHeight - 1; + + unsafe + { + byte* bitmapDataScan0 = (byte*)bitmapData.Scan0; + fixed (byte* pSourceFixed = &buffer[offset]) + { + byte* pSource = bitmapDataScan0 + bitmapDataStride * backBufferHeightMinusOne; + byte* pDestBuffer = pSourceFixed; + for (int y = 0; y < screenCapture.Height; y++) + { + int* pSourceInt = (int*)pSource; + pSourceInt -= (bitmapDataStride * y / 4); + + int* pDestBufferInt = (int*)pDestBuffer; + pDestBufferInt += (backBufferStrideInBytes * y / 4); + + for (int x = 0; x < screenCapture.Width; x++) + { + pDestBufferInt[x] = pSourceInt[x]; + } + } + } + } + + bmpScreenCapture.UnlockBits(bitmapData); + + bmpScreenCapture.Dispose(); + + return screenCapture; + } + + public bool ImageExists(ImageBuffer image) + { + return false; + } + + public bool ImageExists(string imageFileName) + { + return false; + } + + public void Wait(double timeInSeconds) + { + Thread.Sleep((int)(timeInSeconds * 1000)); + } + } +} \ No newline at end of file diff --git a/TestRunner/TestRunner.csproj b/TestRunner/TestRunner.csproj new file mode 100644 index 000000000..2a14e5eff --- /dev/null +++ b/TestRunner/TestRunner.csproj @@ -0,0 +1,163 @@ + + + + Release + AnyCPU + 8.0.50727 + 2.0 + {9D193B5C-BEF4-44B2-AD6D-597B7A2C52C5} + Library + Properties + MatterHackers.TestRunner + TestRunner + + + + + 2.0 + v4.5 + + + + True + full + False + ..\bin\Debug\ + DEBUG;TRACE + prompt + 4 + True + x86 + false + + + pdbonly + True + ..\bin\Release\ + TRACE + prompt + 4 + True + x86 + false + + + false + + + bin\Release64\ + TRACE + true + true + pdbonly + x64 + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + false + + + true + bin\Debug64\ + DEBUG;TRACE + true + full + x86 + prompt + false + false + + + true + bin\x64\Debug\ + DEBUG;TRACE + true + full + x64 + prompt + false + false + false + + + bin\x64\Release\ + TRACE + true + true + pdbonly + x64 + prompt + false + false + false + + + bin\x64\Release64\ + TRACE + true + true + pdbonly + x64 + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + false + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + false + false + + + true + bin\x64\Debug64\ + DEBUG;TRACE + true + full + x64 + prompt + false + false + false + + + + + + + + + + + + {657DBC6D-C3EA-4398-A3FA-DDB73C14F71B} + Agg + + + {74F6BB6C-9D02-4512-A59A-21940E35C532} + Gui + + + {036BCCBA-52D8-457C-84AE-8821F209FE4A} + ImageProcessing + + + {D3E41B4E-BFBB-44CA-94C8-95C00F754FDD} + VectorMath + + + + + + + + + + + \ No newline at end of file diff --git a/TestRunner/app.config b/TestRunner/app.config new file mode 100644 index 000000000..f4aff65b5 --- /dev/null +++ b/TestRunner/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file