correctin file ending (#5970)

This commit is contained in:
Clint Rutkas
2020-08-14 15:10:06 -07:00
committed by GitHub
parent 2ce16bcdb7
commit be36b4aac1
17 changed files with 2734 additions and 2734 deletions

View File

@@ -1,45 +1,45 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Drawing;
using System.Runtime.InteropServices;
namespace Common.ComInterlop
{
/// <summary>
/// The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
/// <summary>
/// Specifies the x-coordinate of the upper-left corner of the rectangle.
/// </summary>
public int Left;
/// <summary>
/// Specifies the y-coordinate of the upper-left corner of the rectangle.
/// </summary>
public int Top;
/// <summary>
/// Specifies the x-coordinate of the lower-right corner of the rectangle.
/// </summary>
public int Right;
/// <summary>
/// Specifies the y-coordinate of the lower-right corner of the rectangle.
/// </summary>
public int Bottom;
/// <summary>
/// Creates a <see cref="Rectangle" /> structure with the edge locations specified in the struct.
/// </summary>
/// <returns>Return a <see cref="Rectangle"/>.</returns>
public Rectangle ToRectangle()
{
return Rectangle.FromLTRB(this.Left, this.Top, this.Right, this.Bottom);
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Drawing;
using System.Runtime.InteropServices;
namespace Common.ComInterlop
{
/// <summary>
/// The RECT structure defines a rectangle by the coordinates of its upper-left and lower-right corners.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
/// <summary>
/// Specifies the x-coordinate of the upper-left corner of the rectangle.
/// </summary>
public int Left;
/// <summary>
/// Specifies the y-coordinate of the upper-left corner of the rectangle.
/// </summary>
public int Top;
/// <summary>
/// Specifies the x-coordinate of the lower-right corner of the rectangle.
/// </summary>
public int Right;
/// <summary>
/// Specifies the y-coordinate of the lower-right corner of the rectangle.
/// </summary>
public int Bottom;
/// <summary>
/// Creates a <see cref="Rectangle" /> structure with the edge locations specified in the struct.
/// </summary>
/// <returns>Return a <see cref="Rectangle"/>.</returns>
public Rectangle ToRectangle()
{
return Rectangle.FromLTRB(this.Left, this.Top, this.Right, this.Bottom);
}
}
}

View File

@@ -1,185 +1,185 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Common
{
/// <summary>
/// Form based implementation of <see cref="IPreviewHandlerControl"/>.
/// </summary>
public abstract class FormHandlerControl : Form, IPreviewHandlerControl
{
/// <summary>
/// Needed to make the form a child window.
/// </summary>
private static int gwlStyle = -16;
private static int wsChild = 0x40000000;
/// <summary>
/// Holds the parent window handle.
/// </summary>
private IntPtr parentHwnd;
/// <summary>
/// Initializes a new instance of the <see cref="FormHandlerControl"/> class.
/// </summary>
public FormHandlerControl()
{
// Gets the handle of the control to create the control on the VI thread. Invoking the Control.Handle get accessor forces the creation of the underlying window for the control.
// This is important, because the thread that instantiates the preview handler component and calls its constructor is a single-threaded apartment (STA) thread, but the thread that calls into the interface members later on is a multithreaded apartment (MTA) thread. Windows Forms controls are meant to run on STA threads.
// More details: https://docs.microsoft.com/en-us/archive/msdn-magazine/2007/january/windows-vista-and-office-writing-your-own-preview-handlers.
var forceCreation = this.Handle;
this.FormBorderStyle = FormBorderStyle.None;
this.Visible = false;
}
/// <inheritdoc />
public IntPtr GetHandle()
{
return this.Handle;
}
/// <inheritdoc />
public void QueryFocus(out IntPtr result)
{
var getResult = IntPtr.Zero;
this.InvokeOnControlThread(() =>
{
getResult = GetFocus();
});
result = getResult;
}
/// <inheritdoc />
public void SetBackgroundColor(Color argbColor)
{
this.InvokeOnControlThread(() =>
{
this.BackColor = argbColor;
});
}
/// <inheritdoc />
public void SetFocus()
{
this.InvokeOnControlThread(() =>
{
this.Focus();
});
}
/// <inheritdoc />
public void SetFont(Font font)
{
this.InvokeOnControlThread(() =>
{
this.Font = font;
});
}
/// <inheritdoc />
public void SetRect(Rectangle windowBounds)
{
this.UpdateWindowBounds(windowBounds);
}
/// <inheritdoc />
public void SetTextColor(Color color)
{
this.InvokeOnControlThread(() =>
{
this.ForeColor = color;
});
}
/// <inheritdoc />
public void SetWindow(IntPtr hwnd, Rectangle rect)
{
this.parentHwnd = hwnd;
this.UpdateWindowBounds(rect);
}
/// <inheritdoc />
public virtual void Unload()
{
this.InvokeOnControlThread(() =>
{
this.Visible = false;
foreach (Control c in this.Controls)
{
c.Dispose();
}
this.Controls.Clear();
});
// Call garbage collection at the time of unloading of Preview. This is to mitigate issue with WebBrowser Control not able to dispose properly.
// Which is preventing prevhost.exe to exit at the time of closing File explorer.
// Preview Handlers run in a separate process from PowerToys. This will not affect the performance of other modules.
// Mitigate the following Github issue: https://github.com/microsoft/PowerToys/issues/1468
GC.Collect();
}
/// <inheritdoc />
public virtual void DoPreview<T>(T dataSource)
{
this.Visible = true;
}
/// <summary>
/// Executes the specified delegate on the thread that owns the control's underlying window handle.
/// </summary>
/// <param name="func">Delegate to run.</param>
public void InvokeOnControlThread(MethodInvoker func)
{
this.Invoke(func);
}
/// <summary>
/// Changes the parent window of the specified child window.
/// </summary>
/// <param name="hWndChild">A handle to the child window.</param>
/// <param name="hWndNewParent">A handle to the new parent window.</param>
/// <returns>If the function succeeds, the return value is a handle to the previous parent window and NULL in case of failure.</returns>
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
/// <summary>
/// Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
/// </summary>
/// <returns>The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr GetFocus();
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
/// <summary>
/// Update the Form Control window with the passed rectangle.
/// </summary>
/// <param name="windowBounds">An instance of rectangle.</param>
private void UpdateWindowBounds(Rectangle windowBounds)
{
this.InvokeOnControlThread(() =>
{
// We must set the WS_CHILD style to change the form to a control within the Explorer preview pane
int windowStyle = GetWindowLong(this.Handle, gwlStyle);
if ((windowStyle & wsChild) == 0)
{
SetWindowLong(this.Handle, gwlStyle, windowStyle | wsChild);
}
SetParent(this.Handle, this.parentHwnd);
this.Bounds = windowBounds;
});
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Common
{
/// <summary>
/// Form based implementation of <see cref="IPreviewHandlerControl"/>.
/// </summary>
public abstract class FormHandlerControl : Form, IPreviewHandlerControl
{
/// <summary>
/// Needed to make the form a child window.
/// </summary>
private static int gwlStyle = -16;
private static int wsChild = 0x40000000;
/// <summary>
/// Holds the parent window handle.
/// </summary>
private IntPtr parentHwnd;
/// <summary>
/// Initializes a new instance of the <see cref="FormHandlerControl"/> class.
/// </summary>
public FormHandlerControl()
{
// Gets the handle of the control to create the control on the VI thread. Invoking the Control.Handle get accessor forces the creation of the underlying window for the control.
// This is important, because the thread that instantiates the preview handler component and calls its constructor is a single-threaded apartment (STA) thread, but the thread that calls into the interface members later on is a multithreaded apartment (MTA) thread. Windows Forms controls are meant to run on STA threads.
// More details: https://docs.microsoft.com/en-us/archive/msdn-magazine/2007/january/windows-vista-and-office-writing-your-own-preview-handlers.
var forceCreation = this.Handle;
this.FormBorderStyle = FormBorderStyle.None;
this.Visible = false;
}
/// <inheritdoc />
public IntPtr GetHandle()
{
return this.Handle;
}
/// <inheritdoc />
public void QueryFocus(out IntPtr result)
{
var getResult = IntPtr.Zero;
this.InvokeOnControlThread(() =>
{
getResult = GetFocus();
});
result = getResult;
}
/// <inheritdoc />
public void SetBackgroundColor(Color argbColor)
{
this.InvokeOnControlThread(() =>
{
this.BackColor = argbColor;
});
}
/// <inheritdoc />
public void SetFocus()
{
this.InvokeOnControlThread(() =>
{
this.Focus();
});
}
/// <inheritdoc />
public void SetFont(Font font)
{
this.InvokeOnControlThread(() =>
{
this.Font = font;
});
}
/// <inheritdoc />
public void SetRect(Rectangle windowBounds)
{
this.UpdateWindowBounds(windowBounds);
}
/// <inheritdoc />
public void SetTextColor(Color color)
{
this.InvokeOnControlThread(() =>
{
this.ForeColor = color;
});
}
/// <inheritdoc />
public void SetWindow(IntPtr hwnd, Rectangle rect)
{
this.parentHwnd = hwnd;
this.UpdateWindowBounds(rect);
}
/// <inheritdoc />
public virtual void Unload()
{
this.InvokeOnControlThread(() =>
{
this.Visible = false;
foreach (Control c in this.Controls)
{
c.Dispose();
}
this.Controls.Clear();
});
// Call garbage collection at the time of unloading of Preview. This is to mitigate issue with WebBrowser Control not able to dispose properly.
// Which is preventing prevhost.exe to exit at the time of closing File explorer.
// Preview Handlers run in a separate process from PowerToys. This will not affect the performance of other modules.
// Mitigate the following Github issue: https://github.com/microsoft/PowerToys/issues/1468
GC.Collect();
}
/// <inheritdoc />
public virtual void DoPreview<T>(T dataSource)
{
this.Visible = true;
}
/// <summary>
/// Executes the specified delegate on the thread that owns the control's underlying window handle.
/// </summary>
/// <param name="func">Delegate to run.</param>
public void InvokeOnControlThread(MethodInvoker func)
{
this.Invoke(func);
}
/// <summary>
/// Changes the parent window of the specified child window.
/// </summary>
/// <param name="hWndChild">A handle to the child window.</param>
/// <param name="hWndNewParent">A handle to the new parent window.</param>
/// <returns>If the function succeeds, the return value is a handle to the previous parent window and NULL in case of failure.</returns>
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
/// <summary>
/// Retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue.
/// </summary>
/// <returns>The return value is the handle to the window with the keyboard focus. If the calling thread's message queue does not have an associated window with the keyboard focus, the return value is NULL.</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr GetFocus();
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", SetLastError = true)]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
/// <summary>
/// Update the Form Control window with the passed rectangle.
/// </summary>
/// <param name="windowBounds">An instance of rectangle.</param>
private void UpdateWindowBounds(Rectangle windowBounds)
{
this.InvokeOnControlThread(() =>
{
// We must set the WS_CHILD style to change the form to a control within the Explorer preview pane
int windowStyle = GetWindowLong(this.Handle, gwlStyle);
if ((windowStyle & wsChild) == 0)
{
SetWindowLong(this.Handle, gwlStyle, windowStyle | wsChild);
}
SetParent(this.Handle, this.parentHwnd);
this.Bounds = windowBounds;
});
}
}
}

View File

@@ -1,77 +1,77 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Drawing;
namespace Common
{
/// <summary>
/// Interface defining methods requirement by the <see cref="PreviewHandlerBase"/> control.
/// </summary>
public interface IPreviewHandlerControl
{
/// <summary>
/// Directs the preview handler to return the HWND from calling the GetFocus function.
/// Source: https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ipreviewhandler-queryfocus.
/// </summary>
/// <param name="result">Returns the handle of the window with focus.</param>
void QueryFocus(out IntPtr result);
/// <summary>
/// Sets focus to the control.
/// </summary>
void SetFocus();
/// <summary>
/// Sets the font according to the font set in Windows Settings.
/// More details: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#ipreviewhandlervisualssetfont.
/// </summary>
/// <param name="font">Instance of Font.</param>
void SetFont(Font font);
/// <summary>
/// Sets the Text color according to the Windows Settings.
/// </summary>
/// <param name="color">Instance of color.</param>
void SetTextColor(Color color);
/// <summary>
/// Sets the Background color. For instance to fill the window when the handler renders to area smaller provided by SetWindow and SetRect.
/// </summary>
/// <param name="argbColor">Instance of color.</param>
void SetBackgroundColor(Color argbColor);
/// <summary>
/// Gets the HWND of the control window.
/// </summary>
/// <returns>Pointer to the window handle.</returns>
IntPtr GetHandle();
/// <summary>
/// Hide the preview and free any resource used for the preview.
/// </summary>
void Unload();
/// <summary>
/// Directs the control to change the area within the parent hwnd that it draws into.
/// </summary>
/// <param name="windowBounds">Instance of Rectangle defining the area.</param>
void SetRect(Rectangle windowBounds);
/// <summary>
/// Sets the parent window of the previewer window, as well as the area within the parent to be used for the previewer window..
/// </summary>
/// <param name="hwnd">Pointer to the parent window handle.</param>
/// <param name="rect">Instance of Rectangle defining the area.</param>
void SetWindow(IntPtr hwnd, Rectangle rect);
/// <summary>
/// Called by Preview Handler to start the preview.
/// </summary>
/// <typeparam name="T">File Path or Stream reference for the file.</typeparam>
/// <param name="dataSource">Represents the source of preview data.</param>
void DoPreview<T>(T dataSource);
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Drawing;
namespace Common
{
/// <summary>
/// Interface defining methods requirement by the <see cref="PreviewHandlerBase"/> control.
/// </summary>
public interface IPreviewHandlerControl
{
/// <summary>
/// Directs the preview handler to return the HWND from calling the GetFocus function.
/// Source: https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ipreviewhandler-queryfocus.
/// </summary>
/// <param name="result">Returns the handle of the window with focus.</param>
void QueryFocus(out IntPtr result);
/// <summary>
/// Sets focus to the control.
/// </summary>
void SetFocus();
/// <summary>
/// Sets the font according to the font set in Windows Settings.
/// More details: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#ipreviewhandlervisualssetfont.
/// </summary>
/// <param name="font">Instance of Font.</param>
void SetFont(Font font);
/// <summary>
/// Sets the Text color according to the Windows Settings.
/// </summary>
/// <param name="color">Instance of color.</param>
void SetTextColor(Color color);
/// <summary>
/// Sets the Background color. For instance to fill the window when the handler renders to area smaller provided by SetWindow and SetRect.
/// </summary>
/// <param name="argbColor">Instance of color.</param>
void SetBackgroundColor(Color argbColor);
/// <summary>
/// Gets the HWND of the control window.
/// </summary>
/// <returns>Pointer to the window handle.</returns>
IntPtr GetHandle();
/// <summary>
/// Hide the preview and free any resource used for the preview.
/// </summary>
void Unload();
/// <summary>
/// Directs the control to change the area within the parent hwnd that it draws into.
/// </summary>
/// <param name="windowBounds">Instance of Rectangle defining the area.</param>
void SetRect(Rectangle windowBounds);
/// <summary>
/// Sets the parent window of the previewer window, as well as the area within the parent to be used for the previewer window..
/// </summary>
/// <param name="hwnd">Pointer to the parent window handle.</param>
/// <param name="rect">Instance of Rectangle defining the area.</param>
void SetWindow(IntPtr hwnd, Rectangle rect);
/// <summary>
/// Called by Preview Handler to start the preview.
/// </summary>
/// <typeparam name="T">File Path or Stream reference for the file.</typeparam>
/// <param name="dataSource">Represents the source of preview data.</param>
void DoPreview<T>(T dataSource);
}
}

View File

@@ -1,35 +1,35 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using System.Windows.Forms;
namespace Common
{
/// <summary>
/// This is test custom control to test the implementation.
/// </summary>
public class CustomControlTest : FormHandlerControl
{
/// <summary>
/// Start the preview on the Control.
/// </summary>
/// <param name="dataSource">Path to the file.</param>
public override void DoPreview<T>(T dataSource)
{
this.InvokeOnControlThread(() =>
{
var filePath = dataSource as string;
WebBrowser browser = new WebBrowser();
browser.DocumentText = "Test";
browser.Navigate(filePath);
browser.Dock = DockStyle.Fill;
browser.IsWebBrowserContextMenuEnabled = false;
this.Controls.Add(browser);
base.DoPreview(dataSource);
});
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO;
using System.Windows.Forms;
namespace Common
{
/// <summary>
/// This is test custom control to test the implementation.
/// </summary>
public class CustomControlTest : FormHandlerControl
{
/// <summary>
/// Start the preview on the Control.
/// </summary>
/// <param name="dataSource">Path to the file.</param>
public override void DoPreview<T>(T dataSource)
{
this.InvokeOnControlThread(() =>
{
var filePath = dataSource as string;
WebBrowser browser = new WebBrowser();
browser.DocumentText = "Test";
browser.Navigate(filePath);
browser.Dock = DockStyle.Fill;
browser.IsWebBrowserContextMenuEnabled = false;
this.Controls.Add(browser);
base.DoPreview(dataSource);
});
}
}
}

View File

@@ -1,32 +1,32 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
namespace Common
{
/// <summary>
/// This is a example custom handler to show how to extend the library.
/// </summary>
[Guid("22a1a8e8-e929-4732-90ce-91eaff38b614")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class TestCustomHandler : FileBasedPreviewHandler
{
private CustomControlTest previewHandlerControl;
/// <inheritdoc />
public override void DoPreview()
{
this.previewHandlerControl.DoPreview(this.FilePath);
}
/// <inheritdoc />
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
this.previewHandlerControl = new CustomControlTest();
return this.previewHandlerControl;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
namespace Common
{
/// <summary>
/// This is a example custom handler to show how to extend the library.
/// </summary>
[Guid("22a1a8e8-e929-4732-90ce-91eaff38b614")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class TestCustomHandler : FileBasedPreviewHandler
{
private CustomControlTest previewHandlerControl;
/// <inheritdoc />
public override void DoPreview()
{
this.previewHandlerControl.DoPreview(this.FilePath);
}
/// <inheritdoc />
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
this.previewHandlerControl = new CustomControlTest();
return this.previewHandlerControl;
}
}
}

View File

@@ -1,27 +1,27 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using Common.Cominterop;
namespace Common
{
/// <summary>
/// Extends the <see cref="PreviewHandlerBase" /> by implementing IInitializeWithFile.
/// </summary>
public abstract class FileBasedPreviewHandler : PreviewHandlerBase, IInitializeWithFile
{
/// <summary>
/// Gets the file path.
/// </summary>
public string FilePath { get; private set; }
/// <inheritdoc />
public void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode)
{
// Ignore the grfMode always use read mode to access the file.
this.FilePath = pszFilePath;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices;
using Common.Cominterop;
namespace Common
{
/// <summary>
/// Extends the <see cref="PreviewHandlerBase" /> by implementing IInitializeWithFile.
/// </summary>
public abstract class FileBasedPreviewHandler : PreviewHandlerBase, IInitializeWithFile
{
/// <summary>
/// Gets the file path.
/// </summary>
public string FilePath { get; private set; }
/// <inheritdoc />
public void Initialize([MarshalAs(UnmanagedType.LPWStr)] string pszFilePath, uint grfMode)
{
// Ignore the grfMode always use read mode to access the file.
this.FilePath = pszFilePath;
}
}
}

View File

@@ -1,158 +1,158 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using Common.ComInterlop;
using Microsoft.Win32;
namespace Common
{
/// <summary>
/// Preview Handler base class implementing interfaces required by Preview Handler.
/// </summary>
public abstract class PreviewHandlerBase : IPreviewHandler, IOleWindow, IObjectWithSite, IPreviewHandlerVisuals
{
/// <summary>
/// An instance of Preview Control Used by the Handler.
/// </summary>
private IPreviewHandlerControl previewControl;
/// <summary>
/// Hold reference for the window handle.
/// </summary>
private IntPtr parentHwnd;
/// <summary>
/// Hold the bounds of the window.
/// </summary>
private Rectangle windowBounds;
/// <summary>
/// Holds the site pointer.
/// </summary>
private object unkSite;
/// <summary>
/// Holds reference for the IPreviewHandlerFrame.
/// </summary>
private IPreviewHandlerFrame frame;
/// <summary>
/// Initializes a new instance of the <see cref="PreviewHandlerBase"/> class.
/// </summary>
public PreviewHandlerBase()
{
this.previewControl = this.CreatePreviewHandlerControl();
}
/// <inheritdoc />
public abstract void DoPreview();
/// <inheritdoc />
public void SetWindow(IntPtr hwnd, ref RECT rect)
{
this.parentHwnd = hwnd;
this.windowBounds = rect.ToRectangle();
this.previewControl.SetWindow(hwnd, this.windowBounds);
}
/// <inheritdoc />
public void SetRect(ref RECT rect)
{
this.windowBounds = rect.ToRectangle();
this.previewControl.SetRect(this.windowBounds);
}
/// <inheritdoc />
public void Unload()
{
this.previewControl.Unload();
}
/// <inheritdoc />
public void SetFocus()
{
this.previewControl.SetFocus();
}
/// <inheritdoc />
public void QueryFocus(out IntPtr phwnd)
{
this.previewControl.QueryFocus(out IntPtr result);
phwnd = result;
if (phwnd == IntPtr.Zero)
{
throw new Win32Exception();
}
}
/// <inheritdoc />
public uint TranslateAccelerator(ref MSG pmsg)
{
// Current implementation simply directs all Keystrokes to IPreviewHandlerFrame. This is the recommended approach to handle keystokes for all low-integrity preview handlers.
// Source: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#ipreviewhandlertranslateaccelerator
if (this.frame != null)
{
return this.frame.TranslateAccelerator(ref pmsg);
}
const uint S_FALSE = 1;
return S_FALSE;
}
/// <inheritdoc />
public void GetWindow(out IntPtr phwnd)
{
phwnd = this.previewControl.GetHandle();
}
/// <inheritdoc />
public void ContextSensitiveHelp(bool fEnterMode)
{
// Should always return NotImplementedException. Source: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#iolewindowcontextsensitivehelp
throw new NotImplementedException();
}
/// <inheritdoc />
public void SetSite(object pUnkSite)
{
// Implementation logic details: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#iobjectwithsitesetsite
this.unkSite = pUnkSite;
this.frame = this.unkSite as IPreviewHandlerFrame;
}
/// <inheritdoc />
public void GetSite(ref Guid riid, out object ppvSite)
{
ppvSite = this.unkSite;
}
/// <inheritdoc />
public void SetBackgroundColor(COLORREF color)
{
this.previewControl.SetBackgroundColor(color.Color);
}
/// <inheritdoc />
public void SetFont(ref LOGFONT plf)
{
this.previewControl.SetFont(Font.FromLogFont(plf));
}
/// <inheritdoc />
public void SetTextColor(COLORREF color)
{
this.previewControl.SetTextColor(color.Color);
}
/// <summary>
/// Provide instance of the implementation of <see cref="IPreviewHandlerControl"/>. Should be overridden by the implementation class with a control object to be used.
/// </summary>
/// <returns>Instance of the <see cref="IPreviewHandlerControl"/>.</returns>
protected abstract IPreviewHandlerControl CreatePreviewHandlerControl();
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using Common.ComInterlop;
using Microsoft.Win32;
namespace Common
{
/// <summary>
/// Preview Handler base class implementing interfaces required by Preview Handler.
/// </summary>
public abstract class PreviewHandlerBase : IPreviewHandler, IOleWindow, IObjectWithSite, IPreviewHandlerVisuals
{
/// <summary>
/// An instance of Preview Control Used by the Handler.
/// </summary>
private IPreviewHandlerControl previewControl;
/// <summary>
/// Hold reference for the window handle.
/// </summary>
private IntPtr parentHwnd;
/// <summary>
/// Hold the bounds of the window.
/// </summary>
private Rectangle windowBounds;
/// <summary>
/// Holds the site pointer.
/// </summary>
private object unkSite;
/// <summary>
/// Holds reference for the IPreviewHandlerFrame.
/// </summary>
private IPreviewHandlerFrame frame;
/// <summary>
/// Initializes a new instance of the <see cref="PreviewHandlerBase"/> class.
/// </summary>
public PreviewHandlerBase()
{
this.previewControl = this.CreatePreviewHandlerControl();
}
/// <inheritdoc />
public abstract void DoPreview();
/// <inheritdoc />
public void SetWindow(IntPtr hwnd, ref RECT rect)
{
this.parentHwnd = hwnd;
this.windowBounds = rect.ToRectangle();
this.previewControl.SetWindow(hwnd, this.windowBounds);
}
/// <inheritdoc />
public void SetRect(ref RECT rect)
{
this.windowBounds = rect.ToRectangle();
this.previewControl.SetRect(this.windowBounds);
}
/// <inheritdoc />
public void Unload()
{
this.previewControl.Unload();
}
/// <inheritdoc />
public void SetFocus()
{
this.previewControl.SetFocus();
}
/// <inheritdoc />
public void QueryFocus(out IntPtr phwnd)
{
this.previewControl.QueryFocus(out IntPtr result);
phwnd = result;
if (phwnd == IntPtr.Zero)
{
throw new Win32Exception();
}
}
/// <inheritdoc />
public uint TranslateAccelerator(ref MSG pmsg)
{
// Current implementation simply directs all Keystrokes to IPreviewHandlerFrame. This is the recommended approach to handle keystokes for all low-integrity preview handlers.
// Source: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#ipreviewhandlertranslateaccelerator
if (this.frame != null)
{
return this.frame.TranslateAccelerator(ref pmsg);
}
const uint S_FALSE = 1;
return S_FALSE;
}
/// <inheritdoc />
public void GetWindow(out IntPtr phwnd)
{
phwnd = this.previewControl.GetHandle();
}
/// <inheritdoc />
public void ContextSensitiveHelp(bool fEnterMode)
{
// Should always return NotImplementedException. Source: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#iolewindowcontextsensitivehelp
throw new NotImplementedException();
}
/// <inheritdoc />
public void SetSite(object pUnkSite)
{
// Implementation logic details: https://docs.microsoft.com/en-us/windows/win32/shell/building-preview-handlers#iobjectwithsitesetsite
this.unkSite = pUnkSite;
this.frame = this.unkSite as IPreviewHandlerFrame;
}
/// <inheritdoc />
public void GetSite(ref Guid riid, out object ppvSite)
{
ppvSite = this.unkSite;
}
/// <inheritdoc />
public void SetBackgroundColor(COLORREF color)
{
this.previewControl.SetBackgroundColor(color.Color);
}
/// <inheritdoc />
public void SetFont(ref LOGFONT plf)
{
this.previewControl.SetFont(Font.FromLogFont(plf));
}
/// <inheritdoc />
public void SetTextColor(COLORREF color)
{
this.previewControl.SetTextColor(color.Color);
}
/// <summary>
/// Provide instance of the implementation of <see cref="IPreviewHandlerControl"/>. Should be overridden by the implementation class with a control object to be used.
/// </summary>
/// <returns>Instance of the <see cref="IPreviewHandlerControl"/>.</returns>
protected abstract IPreviewHandlerControl CreatePreviewHandlerControl();
}
}

View File

@@ -1,27 +1,27 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices.ComTypes;
using Common.ComInterlop;
namespace Common
{
/// <summary>
/// Extends the <see cref="PreviewHandlerBase" /> by implementing IInitializeWithStream.
/// </summary>
public abstract class StreamBasedPreviewHandler : PreviewHandlerBase, IInitializeWithStream
{
/// <summary>
/// Gets the stream object to access file.
/// </summary>
public IStream Stream { get; private set; }
/// <inheritdoc/>
public void Initialize(IStream pstream, uint grfMode)
{
// Ignore the grfMode always use read mode to access the file.
this.Stream = pstream;
}
}
}
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Runtime.InteropServices.ComTypes;
using Common.ComInterlop;
namespace Common
{
/// <summary>
/// Extends the <see cref="PreviewHandlerBase" /> by implementing IInitializeWithStream.
/// </summary>
public abstract class StreamBasedPreviewHandler : PreviewHandlerBase, IInitializeWithStream
{
/// <summary>
/// Gets the stream object to access file.
/// </summary>
public IStream Stream { get; private set; }
/// <inheritdoc/>
public void Initialize(IStream pstream, uint grfMode)
{
// Ignore the grfMode always use read mode to access the file.
this.Stream = pstream;
}
}
}

View File

@@ -1,304 +1,304 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System.Windows.Forms;
namespace PowerToysTests
{
[TestClass]
public class FancyZonesEditorCanvasZoneResizeTests : FancyZonesEditor
{
private void MoveCorner(WindowsElement corner, bool shiftLeft, bool shiftUp, int xOffset, int yOffset)
{
int shiftX = shiftLeft ? -(corner.Rect.Width / 2) + 1 : (corner.Rect.Width / 2) - 1;
int shiftY = shiftUp ? -(corner.Rect.Height / 2) + 1 : (corner.Rect.Height / 2) - 1;
new Actions(session).MoveToElement(corner)
.MoveByOffset(shiftX, shiftY)
.ClickAndHold().MoveByOffset(xOffset, yOffset).Release().Perform();
}
[TestMethod]
public void MoveTopBorder()
{
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
Assert.IsNotNull(topBorder);
Assert.IsNotNull(bottomBorder);
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//up
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
Assert.IsTrue(topBorder.Rect.Y >= 0);
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//down
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
}
[TestMethod]
public void MoveBottomBorder()
{
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
Assert.IsNotNull(topBorder);
Assert.IsNotNull(bottomBorder);
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//up
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//down
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
Assert.IsTrue(bottomBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
}
[TestMethod]
public void MoveLeftBorder()
{
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(leftBorder);
Assert.IsNotNull(rightBorder);
int width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the left
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the right
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
}
[TestMethod]
public void MoveRightBorder()
{
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(leftBorder);
Assert.IsNotNull(rightBorder);
int width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the left
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the right
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
}
[TestMethod]
public void MoveTopLeftCorner()
{
WindowsElement topLeftCorner = session.FindElementByAccessibilityId("NWResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(topLeftCorner);
Assert.IsNotNull(bottomBorder);
Assert.IsNotNull(rightBorder);
int expectedWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
int expectedHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
int actualWidth, actualHeight;
//up-left
MoveCorner(topLeftCorner, true, true, -5000, -5000);
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
Assert.IsTrue(actualHeight > expectedHeight);
Assert.IsTrue(actualWidth > expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-right
MoveCorner(topLeftCorner, true, true, 5000, 5000);
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
}
[TestMethod]
public void MoveTopRightCorner()
{
WindowsElement topRightCorner = session.FindElementByAccessibilityId("NEResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
Assert.IsNotNull(topRightCorner);
Assert.IsNotNull(bottomBorder);
Assert.IsNotNull(leftBorder);
int expectedWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
int expectedHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
int actualWidth, actualHeight;
//up-right
MoveCorner(topRightCorner, false, true, 5000, -5000);
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
Assert.IsTrue(actualHeight > expectedHeight);
Assert.IsTrue(actualWidth > expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-left
MoveCorner(topRightCorner, false, true, -5000, 5000);
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
}
[TestMethod]
public void MoveBottomLeftCorner()
{
WindowsElement bottomLeftCorner = session.FindElementByAccessibilityId("SWResize");
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(bottomLeftCorner);
Assert.IsNotNull(topBorder);
Assert.IsNotNull(rightBorder);
int expectedWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
int expectedHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
int actualWidth, actualHeight;
//up-left
MoveCorner(bottomLeftCorner, true, false, 5000, -5000);
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-right
MoveCorner(bottomLeftCorner, true, false, -5000, 5000);
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
Assert.IsTrue(actualHeight > expectedHeight);
Assert.IsTrue(actualWidth > expectedWidth);
}
[TestMethod]
public void MoveBottomRightCorner()
{
WindowsElement bottomRightCorner = session.FindElementByAccessibilityId("SEResize");
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
Assert.IsNotNull(bottomRightCorner);
Assert.IsNotNull(topBorder);
Assert.IsNotNull(leftBorder);
int expectedWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
int expectedHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
int actualWidth, actualHeight;
//up-left
MoveCorner(bottomRightCorner, false, false, -5000, -5000);
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-right
MoveCorner(bottomRightCorner, false, false, 5000, 5000);
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
Assert.IsTrue(actualHeight > expectedHeight);
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
return;
ResetSettings();
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenCustomLayouts();
}
[ClassCleanup]
public static void ClassCleanup()
{
CloseEditor();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
if (session == null)
return;
//create canvas zone
OpenCreatorWindow("Create new custom", "Custom layout creator");
session.FindElementByAccessibilityId("newZoneButton").Click();
}
[TestCleanup]
public void TestCleanup()
{
if (session == null)
return;
new Actions(session).MoveToElement(session.FindElementByXPath("//Button[@Name=\"Cancel\"]")).Click().Perform();
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System.Windows.Forms;
namespace PowerToysTests
{
[TestClass]
public class FancyZonesEditorCanvasZoneResizeTests : FancyZonesEditor
{
private void MoveCorner(WindowsElement corner, bool shiftLeft, bool shiftUp, int xOffset, int yOffset)
{
int shiftX = shiftLeft ? -(corner.Rect.Width / 2) + 1 : (corner.Rect.Width / 2) - 1;
int shiftY = shiftUp ? -(corner.Rect.Height / 2) + 1 : (corner.Rect.Height / 2) - 1;
new Actions(session).MoveToElement(corner)
.MoveByOffset(shiftX, shiftY)
.ClickAndHold().MoveByOffset(xOffset, yOffset).Release().Perform();
}
[TestMethod]
public void MoveTopBorder()
{
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
Assert.IsNotNull(topBorder);
Assert.IsNotNull(bottomBorder);
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//up
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
Assert.IsTrue(topBorder.Rect.Y >= 0);
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//down
new Actions(session).MoveToElement(topBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
}
[TestMethod]
public void MoveBottomBorder()
{
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
Assert.IsNotNull(topBorder);
Assert.IsNotNull(bottomBorder);
int height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//up
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, -5000).Release().Perform();
Assert.IsTrue(topBorder.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(height > bottomBorder.Rect.Y - topBorder.Rect.Y);
height = bottomBorder.Rect.Y - topBorder.Rect.Y;
//down
new Actions(session).MoveToElement(bottomBorder).ClickAndHold().MoveByOffset(0, 5000).Release().Perform();
Assert.IsTrue(bottomBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(height < bottomBorder.Rect.Y - topBorder.Rect.Y);
}
[TestMethod]
public void MoveLeftBorder()
{
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(leftBorder);
Assert.IsNotNull(rightBorder);
int width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the left
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the right
new Actions(session).MoveToElement(leftBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
}
[TestMethod]
public void MoveRightBorder()
{
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(leftBorder);
Assert.IsNotNull(rightBorder);
int width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the left
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(-5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(width > rightBorder.Rect.X - leftBorder.Rect.X);
width = rightBorder.Rect.X - leftBorder.Rect.X;
//to the right
new Actions(session).MoveToElement(rightBorder).ClickAndHold().MoveByOffset(5000, 0).Release().Perform();
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
Assert.IsTrue(width < rightBorder.Rect.X - leftBorder.Rect.X);
}
[TestMethod]
public void MoveTopLeftCorner()
{
WindowsElement topLeftCorner = session.FindElementByAccessibilityId("NWResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(topLeftCorner);
Assert.IsNotNull(bottomBorder);
Assert.IsNotNull(rightBorder);
int expectedWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
int expectedHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
int actualWidth, actualHeight;
//up-left
MoveCorner(topLeftCorner, true, true, -5000, -5000);
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
Assert.IsTrue(topLeftCorner.Rect.Y >= 0);
Assert.IsTrue(topLeftCorner.Rect.X >= 0);
Assert.IsTrue(actualHeight > expectedHeight);
Assert.IsTrue(actualWidth > expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-right
MoveCorner(topLeftCorner, true, true, 5000, 5000);
actualHeight = bottomBorder.Rect.Y - topLeftCorner.Rect.Y;
actualWidth = rightBorder.Rect.X - topLeftCorner.Rect.X;
Assert.IsTrue(topLeftCorner.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(topLeftCorner.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
}
[TestMethod]
public void MoveTopRightCorner()
{
WindowsElement topRightCorner = session.FindElementByAccessibilityId("NEResize");
WindowsElement bottomBorder = session.FindElementByAccessibilityId("SResize");
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
Assert.IsNotNull(topRightCorner);
Assert.IsNotNull(bottomBorder);
Assert.IsNotNull(leftBorder);
int expectedWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
int expectedHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
int actualWidth, actualHeight;
//up-right
MoveCorner(topRightCorner, false, true, 5000, -5000);
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(topRightCorner.Rect.Y >= 0);
Assert.IsTrue(leftBorder.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
Assert.IsTrue(actualHeight > expectedHeight);
Assert.IsTrue(actualWidth > expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-left
MoveCorner(topRightCorner, false, true, -5000, 5000);
actualHeight = bottomBorder.Rect.Y - topRightCorner.Rect.Y;
actualWidth = topRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(topRightCorner.Rect.Y <= bottomBorder.Rect.Y);
Assert.IsTrue(topRightCorner.Rect.X >= leftBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
}
[TestMethod]
public void MoveBottomLeftCorner()
{
WindowsElement bottomLeftCorner = session.FindElementByAccessibilityId("SWResize");
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement rightBorder = session.FindElementByAccessibilityId("EResize");
Assert.IsNotNull(bottomLeftCorner);
Assert.IsNotNull(topBorder);
Assert.IsNotNull(rightBorder);
int expectedWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
int expectedHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
int actualWidth, actualHeight;
//up-left
MoveCorner(bottomLeftCorner, true, false, 5000, -5000);
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
Assert.IsTrue(bottomLeftCorner.Rect.Y >= topBorder.Rect.Y);
Assert.IsTrue(bottomLeftCorner.Rect.X <= rightBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-right
MoveCorner(bottomLeftCorner, true, false, -5000, 5000);
actualHeight = bottomLeftCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = rightBorder.Rect.X - bottomLeftCorner.Rect.X;
Assert.IsTrue(bottomLeftCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(bottomLeftCorner.Rect.X >= 0);
Assert.IsTrue(actualHeight > expectedHeight);
Assert.IsTrue(actualWidth > expectedWidth);
}
[TestMethod]
public void MoveBottomRightCorner()
{
WindowsElement bottomRightCorner = session.FindElementByAccessibilityId("SEResize");
WindowsElement topBorder = session.FindElementByAccessibilityId("NResize");
WindowsElement leftBorder = session.FindElementByAccessibilityId("WResize");
Assert.IsNotNull(bottomRightCorner);
Assert.IsNotNull(topBorder);
Assert.IsNotNull(leftBorder);
int expectedWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
int expectedHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
int actualWidth, actualHeight;
//up-left
MoveCorner(bottomRightCorner, false, false, -5000, -5000);
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(bottomRightCorner.Rect.Y >= topBorder.Rect.Y);
Assert.IsTrue(bottomRightCorner.Rect.X >= leftBorder.Rect.X);
Assert.IsTrue(actualHeight < expectedHeight);
Assert.IsTrue(actualWidth < expectedWidth);
expectedHeight = actualHeight;
expectedWidth = actualWidth;
//down-right
MoveCorner(bottomRightCorner, false, false, 5000, 5000);
actualHeight = bottomRightCorner.Rect.Y - topBorder.Rect.Y;
actualWidth = bottomRightCorner.Rect.X - leftBorder.Rect.X;
Assert.IsTrue(bottomRightCorner.Rect.Y <= Screen.PrimaryScreen.WorkingArea.Bottom);
Assert.IsTrue(bottomRightCorner.Rect.X <= Screen.PrimaryScreen.WorkingArea.Right);
Assert.IsTrue(actualHeight > expectedHeight);
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
return;
ResetSettings();
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenCustomLayouts();
}
[ClassCleanup]
public static void ClassCleanup()
{
CloseEditor();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
if (session == null)
return;
//create canvas zone
OpenCreatorWindow("Create new custom", "Custom layout creator");
session.FindElementByAccessibilityId("newZoneButton").Click();
}
[TestCleanup]
public void TestCleanup()
{
if (session == null)
return;
new Actions(session).MoveToElement(session.FindElementByXPath("//Button[@Name=\"Cancel\"]")).Click().Perform();
}
}
}

View File

@@ -1,298 +1,298 @@
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Interactions;
namespace PowerToysTests
{
{
[TestClass]
public class FancyZonesEditorCustomLayoutsTests : FancyZonesEditor
{
private void SetLayoutName(string name)
{
WindowsElement textBox = session.FindElementByClassName("TextBox");
textBox.Click();
{
private void SetLayoutName(string name)
{
WindowsElement textBox = session.FindElementByClassName("TextBox");
textBox.Click();
textBox.SendKeys(Keys.Control + "a");
textBox.SendKeys(Keys.Backspace);
textBox.SendKeys(name);
textBox.SendKeys(Keys.Backspace);
textBox.SendKeys(name);
}
private void CancelTest()
{
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
new Actions(session).MoveToElement(cancelButton).Click().Perform();
WaitSeconds(1);
Assert.AreEqual(_initialZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
private void CancelTest()
{
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
new Actions(session).MoveToElement(cancelButton).Click().Perform();
WaitSeconds(1);
Assert.AreEqual(_initialZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
}
private void SaveTest(string type, string name, int zoneCount)
{
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(name, settings["custom-zone-sets"][0]["name"]);
Assert.AreEqual(settings["custom-zone-sets"][0]["uuid"], settings["devices"][0]["active-zoneset"]["uuid"]);
Assert.AreEqual(type, settings["custom-zone-sets"][0]["type"]);
Assert.AreEqual(zoneCount, settings["custom-zone-sets"][0]["info"]["zones"].ToObject<JArray>().Count);
private void SaveTest(string type, string name, int zoneCount)
{
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(name, settings["custom-zone-sets"][0]["name"]);
Assert.AreEqual(settings["custom-zone-sets"][0]["uuid"], settings["devices"][0]["active-zoneset"]["uuid"]);
Assert.AreEqual(type, settings["custom-zone-sets"][0]["type"]);
Assert.AreEqual(zoneCount, settings["custom-zone-sets"][0]["info"]["zones"].ToObject<JArray>().Count);
}
[TestMethod]
public void CreateCancel()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(1, 0);
CancelTest();
}
[TestMethod]
public void CreateEmpty()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
SaveTest("canvas", "Custom Layout 1", 0);
}
[TestMethod]
public void CreateSingleZone()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(1, 0);
SaveTest("canvas", "Custom Layout 1", 1);
public void CreateCancel()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(1, 0);
CancelTest();
}
[TestMethod]
public void CreateManyZones()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
const int expectedZoneCount = 20;
WindowsElement addButton = session.FindElementByAccessibilityId("newZoneButton");
for (int i = 0; i < expectedZoneCount; i++)
{
addButton.Click();
}
ZoneCountTest(expectedZoneCount, 0);
SaveTest("canvas", "Custom Layout 1", expectedZoneCount);
public void CreateEmpty()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
SaveTest("canvas", "Custom Layout 1", 0);
}
[TestMethod]
public void CreateDeleteZone()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
WindowsElement addButton = session.FindElementByAccessibilityId("newZoneButton");
for (int i = 0; i < 10; i++)
{
//add zone
addButton.Click();
WindowsElement zone = session.FindElementByClassName("CanvasZone");
Assert.IsNotNull(zone, "Zone was not created");
Assert.IsTrue(zone.Displayed, "Zone was not displayed");
//remove zone
zone.FindElementByClassName("Button").Click();
}
ZoneCountTest(0, 0);
CancelTest();
public void CreateSingleZone()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(1, 0);
SaveTest("canvas", "Custom Layout 1", 1);
}
[TestMethod]
public void CreateWithName()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "My custom zone layout name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
public void CreateManyZones()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
const int expectedZoneCount = 20;
WindowsElement addButton = session.FindElementByAccessibilityId("newZoneButton");
for (int i = 0; i < expectedZoneCount; i++)
{
addButton.Click();
}
ZoneCountTest(expectedZoneCount, 0);
SaveTest("canvas", "Custom Layout 1", expectedZoneCount);
}
[TestMethod]
public void CreateWithEmptyName()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "";
SetLayoutName(name);
SaveTest("canvas", name, 0);
}
[TestMethod]
public void CreateWithUnicodeCharactersName()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "ёÖ±¬āݾᵩὡ√ﮘﻹտ";
SetLayoutName(name);
SaveTest("canvas", name, 0);
public void CreateDeleteZone()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
ZoneCountTest(0, 0);
WindowsElement addButton = session.FindElementByAccessibilityId("newZoneButton");
for (int i = 0; i < 10; i++)
{
//add zone
addButton.Click();
WindowsElement zone = session.FindElementByClassName("CanvasZone");
Assert.IsNotNull(zone, "Zone was not created");
Assert.IsTrue(zone.Displayed, "Zone was not displayed");
//remove zone
zone.FindElementByClassName("Button").Click();
}
ZoneCountTest(0, 0);
CancelTest();
}
[TestMethod]
public void RenameLayout()
{
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "My custom zone layout name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
WaitSeconds(1);
//rename layout
OpenEditor();
OpenCustomLayouts();
OpenCreatorWindow(name, "Custom layout creator");
name = "New name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
public void CreateWithName()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "My custom zone layout name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
}
[TestMethod]
public void RemoveLayout()
{
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "Name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
WaitSeconds(1);
//save layout id
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(1, settings["custom-zone-sets"].ToObject<JArray>().Count);
string layoutId = settings["custom-zone-sets"][0]["uuid"].ToString();
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
//settings are saved on window closing
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
WaitSeconds(1);
//check settings
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
foreach (JObject device in settings["devices"].ToObject<JArray>())
{
Assert.AreNotEqual(layoutId, device["active-zoneset"]["uuid"], "Deleted layout still applied");
}
}
[TestMethod]
public void AddRemoveSameLayoutNames()
{
string name = "Name";
for (int i = 0; i < 3; i++)
{
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
SetLayoutName(name);
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
}
//settings are saved on window closing
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
WaitSeconds(1);
//check settings
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
}
[TestMethod]
public void AddRemoveDifferentLayoutNames()
{
for (int i = 0; i < 3; i++)
{
string name = i.ToString();
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
SetLayoutName(name);
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
}
//settings are saved on window closing
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
WaitSeconds(1);
//check settings
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
public void CreateWithEmptyName()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "";
SetLayoutName(name);
SaveTest("canvas", name, 0);
}
[TestMethod]
public void RemoveApply()
{
string name = "Name";
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
SetLayoutName(name);
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
//save layout id
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(1, settings["custom-zone-sets"].ToObject<JArray>().Count);
string layoutId = settings["custom-zone-sets"][0]["uuid"].ToString();
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
//apply
new Actions(session).MoveToElement(session.FindElementByName("Apply")).Click().Perform();
WaitSeconds(1);
//check settings
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
foreach (JObject device in settings["devices"].ToObject<JArray>())
{
Assert.AreNotEqual(layoutId, device["active-zoneset"]["uuid"], "Deleted layout still applied");
}
public void CreateWithUnicodeCharactersName()
{
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "ёÖ±¬āݾᵩὡ√ﮘﻹտ";
SetLayoutName(name);
SaveTest("canvas", name, 0);
}
[TestMethod]
public void RenameLayout()
{
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "My custom zone layout name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
WaitSeconds(1);
//rename layout
OpenEditor();
OpenCustomLayouts();
OpenCreatorWindow(name, "Custom layout creator");
name = "New name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
}
[TestMethod]
public void RemoveLayout()
{
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
string name = "Name";
SetLayoutName(name);
SaveTest("canvas", name, 0);
WaitSeconds(1);
//save layout id
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(1, settings["custom-zone-sets"].ToObject<JArray>().Count);
string layoutId = settings["custom-zone-sets"][0]["uuid"].ToString();
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
//settings are saved on window closing
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
WaitSeconds(1);
//check settings
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
foreach (JObject device in settings["devices"].ToObject<JArray>())
{
Assert.AreNotEqual(layoutId, device["active-zoneset"]["uuid"], "Deleted layout still applied");
}
}
[TestMethod]
public void AddRemoveSameLayoutNames()
{
string name = "Name";
for (int i = 0; i < 3; i++)
{
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
SetLayoutName(name);
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
}
//settings are saved on window closing
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
WaitSeconds(1);
//check settings
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
}
[TestMethod]
public void AddRemoveDifferentLayoutNames()
{
for (int i = 0; i < 3; i++)
{
string name = i.ToString();
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
SetLayoutName(name);
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
}
//settings are saved on window closing
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_Close")).Click().Perform();
WaitSeconds(1);
//check settings
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
}
[TestMethod]
public void RemoveApply()
{
string name = "Name";
//create layout
OpenCreatorWindow("Create new custom", "Custom layout creator");
SetLayoutName(name);
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
//save layout id
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(1, settings["custom-zone-sets"].ToObject<JArray>().Count);
string layoutId = settings["custom-zone-sets"][0]["uuid"].ToString();
//remove layout
OpenEditor();
OpenCustomLayouts();
WindowsElement nameLabel = session.FindElementByXPath("//Text[@Name=\"" + name + "\"]");
new Actions(session).MoveToElement(nameLabel).MoveByOffset(nameLabel.Rect.Width / 2 + 10, 0).Click().Perform();
//apply
new Actions(session).MoveToElement(session.FindElementByName("Apply")).Click().Perform();
WaitSeconds(1);
//check settings
settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(0, settings["custom-zone-sets"].ToObject<JArray>().Count);
foreach (JObject device in settings["devices"].ToObject<JArray>())
{
Assert.AreNotEqual(layoutId, device["active-zoneset"]["uuid"], "Deleted layout still applied");
}
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
if (session == null)
return;
ResetSettings();
@@ -306,23 +306,23 @@ namespace PowerToysTests
[TestInitialize]
public void TestInitialize()
{
if (session == null)
return;
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenCustomLayouts();
{
if (session == null)
return;
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenCustomLayouts();
}
[TestCleanup]
public void TestCleanup()
{
CloseEditor();
ResetDefaultZoneSettings(false);
ResetDefaultZoneSettings(false);
}
}
}

View File

@@ -1,434 +1,434 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System;
using System.Collections.ObjectModel;
using System.Windows.Forms;
namespace PowerToysTests
{
[TestClass]
public class FancyZonesEditorGridZoneResizeTests : FancyZonesEditor
{
private const int moveStep = 5;
private void Move(AppiumWebElement thumb, int border, bool moveAscending, bool moveHorizontally, int clickShift = 0)
{
Actions action = new Actions(session);
action.MoveToElement(thumb).MoveByOffset(0, clickShift).ClickAndHold();
int thumbCenter = 0;
if (moveHorizontally)
{
thumbCenter = thumb.Rect.X + thumb.Rect.Width / 2;
}
else
{
thumbCenter = thumb.Rect.Y + thumb.Rect.Height / 2;
}
int moves = Math.Abs(thumbCenter - border) / moveStep;
for (int j = 0; j < moves; j++)
{
int step = moveAscending ? moveStep : -moveStep;
if (moveHorizontally)
{
action.MoveByOffset(step, 0);
}
else
{
action.MoveByOffset(0, step);
}
}
action.Release().Perform();
}
[TestMethod]
public void MoveVerticalSplitter()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//move left
for (int i = 0; i < thumbs.Count; i++)
{
AppiumWebElement thumb = thumbs[i];
int border = i == 0 ? 0 : thumbs[i - 1].Rect.Right;
Move(thumb, border, false, true);
Assert.IsTrue(thumb.Rect.Left - border <= moveStep);
Assert.IsTrue(thumb.Rect.Right > border);
}
//move right
for (int i = thumbs.Count - 1; i >= 0; i--)
{
AppiumWebElement thumb = thumbs[i];
int border = i == thumbs.Count - 1 ? Screen.PrimaryScreen.WorkingArea.Right : thumbs[i + 1].Rect.Left;
Move(thumb, border, true, true);
Assert.IsTrue(border - thumb.Rect.Right <= moveStep);
Assert.IsTrue(thumb.Rect.Left < border);
}
//move up
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.X;
Move(thumb, 0, false, false);
int actual = thumb.Rect.X;
Assert.AreEqual(expected, actual);
}
//move down
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.X;
Move(thumb, Screen.PrimaryScreen.WorkingArea.Right, false, false);
int actual = thumb.Rect.X;
Assert.AreEqual(expected, actual);
}
}
[TestMethod]
public void MoveHorizontalSplitter()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//move up
for (int i = 0; i < thumbs.Count; i++)
{
AppiumWebElement thumb = thumbs[i];
int border = i == 0 ? 0 : thumbs[i - 1].Rect.Bottom;
Move(thumb, border, false, false);
Assert.IsTrue(thumb.Rect.Top - border <= moveStep);
Assert.IsTrue(thumb.Rect.Right > border);
}
//move down
for (int i = thumbs.Count - 1; i >= 0; i--)
{
AppiumWebElement thumb = thumbs[i];
int border = i == thumbs.Count - 1 ? Screen.PrimaryScreen.WorkingArea.Bottom : thumbs[i + 1].Rect.Top;
Move(thumb, border, true, false);
Assert.IsTrue(border - thumb.Rect.Bottom <= moveStep);
Assert.IsTrue(thumb.Rect.Top < border);
}
//move left
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.Y;
Move(thumb, 0, false, true);
int actual = thumb.Rect.Y;
Assert.AreEqual(expected, actual);
}
//move right
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.Y;
Move(thumb, Screen.PrimaryScreen.WorkingArea.Right, true, true);
int actual = thumb.Rect.Y;
Assert.AreEqual(expected, actual);
}
}
[TestMethod]
public void CreateSplitter()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WaitSeconds(2);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(3, zones.Count, "Zones count invalid");
const int defaultSpacing = 16;
int splitPos = zones[0].Rect.Y + zones[0].Rect.Height / 2;
new Actions(session).MoveToElement(zones[0]).Click().Perform();
zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
//check splitted zone
Assert.AreEqual(zones[0].Rect.Top, defaultSpacing);
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - splitPos + defaultSpacing / 2) <= 2);
Assert.IsTrue(Math.Abs(zones[3].Rect.Top - splitPos - defaultSpacing / 2) <= 2);
Assert.AreEqual(zones[3].Rect.Bottom, Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing);
}
[TestMethod]
public void TestSplitterShiftAfterCreation()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WaitSeconds(2);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(3, zones.Count, "Zones count invalid");
const int defaultSpacing = 16;
//create first split
int firstSplitPos = zones[0].Rect.Y + zones[0].Rect.Height / 4;
new Actions(session).MoveToElement(zones[0]).MoveByOffset(0, -(zones[0].Rect.Height / 4)).Click().Perform();
zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
Assert.AreEqual(zones[0].Rect.Top, defaultSpacing);
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - firstSplitPos + defaultSpacing / 2) <= 2);
Assert.IsTrue(Math.Abs(zones[3].Rect.Top - firstSplitPos - defaultSpacing / 2) <= 2);
Assert.AreEqual(zones[3].Rect.Bottom, Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing);
//create second split
int secondSplitPos = zones[3].Rect.Y + zones[3].Rect.Height / 2;
int expectedTop = zones[3].Rect.Top;
new Actions(session).MoveToElement(zones[3]).Click().Perform();
zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(5, zones.Count);
//check first split on same position
Assert.AreEqual(zones[0].Rect.Top, defaultSpacing);
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - firstSplitPos + defaultSpacing / 2) <= 2);
//check second split
Assert.AreEqual(zones[3].Rect.Top, expectedTop);
Assert.IsTrue(Math.Abs(zones[3].Rect.Bottom - secondSplitPos + defaultSpacing / 2) <= 2);
Assert.IsTrue(Math.Abs(zones[4].Rect.Top - secondSplitPos - defaultSpacing / 2) <= 2);
Assert.AreEqual(zones[4].Rect.Bottom, Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing);
}
[TestMethod]
public void CreateSplitterWithShiftPressed()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(2, thumbs.Count);
new Actions(session).MoveToElement(thumbs[0]).MoveByOffset(-100, 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
Assert.AreEqual(3, gridEditor.FindElementsByClassName("Thumb").Count);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
//check that zone was splitted vertically
Assert.AreEqual(zones[0].Rect.Height, zones[1].Rect.Height);
Assert.AreEqual(zones[1].Rect.Height, zones[2].Rect.Height);
Assert.AreEqual(zones[2].Rect.Height, zones[3].Rect.Height);
}
[TestMethod]
public void CreateSplitterWithShiftPressedFocusOnGridEditor()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(2, thumbs.Count);
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-100, 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
Assert.AreEqual(3, gridEditor.FindElementsByClassName("Thumb").Count);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
//check that zone was splitted vertically
Assert.AreEqual(zones[0].Rect.Height, zones[1].Rect.Height);
Assert.AreEqual(zones[1].Rect.Height, zones[2].Rect.Height);
Assert.AreEqual(zones[2].Rect.Height, zones[3].Rect.Height);
}
[TestMethod]
public void MoveHorizontallyWithLimiter()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//create new zones
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-30, 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(4, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(3, thumbs.Count);
//move thumbs
AppiumWebElement limiter = gridEditor.FindElementsByClassName("Thumb")[0];
AppiumWebElement movable = gridEditor.FindElementsByClassName("Thumb")[1];
Move(movable, 0, false, true);
Assert.IsTrue(movable.Rect.X > limiter.Rect.X);
Assert.IsTrue(movable.Rect.X - limiter.Rect.X < movable.Rect.Width);
Move(limiter, limiter.Rect.X - (limiter.Rect.X / 2), false, true);
Move(movable, 0, false, true);
Assert.IsTrue(movable.Rect.X > limiter.Rect.X);
Assert.IsTrue(movable.Rect.X - limiter.Rect.X < movable.Rect.Width);
}
[TestMethod]
public void MoveVerticallyWithLimiter()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//create new zones
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(0, -(thumbs[0].Rect.Y / 2))
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(4, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(3, thumbs.Count);
//move thumbs
AppiumWebElement limiter = gridEditor.FindElementsByClassName("Thumb")[0];
AppiumWebElement movable = gridEditor.FindElementsByClassName("Thumb")[1];
Move(movable, 0, false, false);
Assert.IsTrue(movable.Rect.Y > limiter.Rect.Y);
Assert.IsTrue(movable.Rect.Y - limiter.Rect.Y < movable.Rect.Height);
Move(limiter, limiter.Rect.Y - (limiter.Rect.Y / 2), false, false, -5);
Move(movable, 0, false, false);
Assert.IsTrue(movable.Rect.Y > limiter.Rect.Y);
Assert.IsTrue(movable.Rect.Y - limiter.Rect.Y < movable.Rect.Height);
}
[TestMethod]
public void MergeZones()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(3, zones.Count);
Assert.AreEqual(2, thumbs.Count);
Move(zones[0], thumbs[0].Rect.X + thumbs[0].Rect.Width + 10, true, true, -(zones[0].Rect.Height / 2) + 10);
WindowsElement mergeButton = session.FindElementByName("Merge zones");
Assert.IsNotNull(mergeButton, "Cannot merge: no merge button");
new Actions(session).Click(mergeButton).Perform();
Assert.AreEqual(2, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(1, gridEditor.FindElementsByClassName("Thumb").Count);
}
[TestMethod]
public void MoveAfterMerge()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
//create new zones
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-(thumbs[0].Rect.X / 2), 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
thumbs = gridEditor.FindElementsByClassName("Thumb");
//merge zones
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Move(zones[0], thumbs[0].Rect.X + thumbs[0].Rect.Width + 10, true, true, -(zones[0].Rect.Height / 2) + 10);
WindowsElement mergeButton = session.FindElementByName("Merge zones");
Assert.IsNotNull(mergeButton, "Cannot merge: no merge button");
new Actions(session).Click(mergeButton).Perform();
//move thumb
AppiumWebElement thumb = thumbs[1]; //thumb from merged zone is still present
Move(thumb, 0, false, true);
Assert.IsTrue(thumb.Rect.Left <= moveStep);
Assert.IsTrue(thumb.Rect.Right > 0);
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
return;
ResetSettings();
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenTemplates();
}
[ClassCleanup]
public static void ClassCleanup()
{
CloseEditor();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
}
[TestCleanup]
public void TestCleanup()
{
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
Assert.IsNotNull(cancelButton);
new Actions(session).MoveToElement(cancelButton).Click().Perform();
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System;
using System.Collections.ObjectModel;
using System.Windows.Forms;
namespace PowerToysTests
{
[TestClass]
public class FancyZonesEditorGridZoneResizeTests : FancyZonesEditor
{
private const int moveStep = 5;
private void Move(AppiumWebElement thumb, int border, bool moveAscending, bool moveHorizontally, int clickShift = 0)
{
Actions action = new Actions(session);
action.MoveToElement(thumb).MoveByOffset(0, clickShift).ClickAndHold();
int thumbCenter = 0;
if (moveHorizontally)
{
thumbCenter = thumb.Rect.X + thumb.Rect.Width / 2;
}
else
{
thumbCenter = thumb.Rect.Y + thumb.Rect.Height / 2;
}
int moves = Math.Abs(thumbCenter - border) / moveStep;
for (int j = 0; j < moves; j++)
{
int step = moveAscending ? moveStep : -moveStep;
if (moveHorizontally)
{
action.MoveByOffset(step, 0);
}
else
{
action.MoveByOffset(0, step);
}
}
action.Release().Perform();
}
[TestMethod]
public void MoveVerticalSplitter()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//move left
for (int i = 0; i < thumbs.Count; i++)
{
AppiumWebElement thumb = thumbs[i];
int border = i == 0 ? 0 : thumbs[i - 1].Rect.Right;
Move(thumb, border, false, true);
Assert.IsTrue(thumb.Rect.Left - border <= moveStep);
Assert.IsTrue(thumb.Rect.Right > border);
}
//move right
for (int i = thumbs.Count - 1; i >= 0; i--)
{
AppiumWebElement thumb = thumbs[i];
int border = i == thumbs.Count - 1 ? Screen.PrimaryScreen.WorkingArea.Right : thumbs[i + 1].Rect.Left;
Move(thumb, border, true, true);
Assert.IsTrue(border - thumb.Rect.Right <= moveStep);
Assert.IsTrue(thumb.Rect.Left < border);
}
//move up
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.X;
Move(thumb, 0, false, false);
int actual = thumb.Rect.X;
Assert.AreEqual(expected, actual);
}
//move down
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.X;
Move(thumb, Screen.PrimaryScreen.WorkingArea.Right, false, false);
int actual = thumb.Rect.X;
Assert.AreEqual(expected, actual);
}
}
[TestMethod]
public void MoveHorizontalSplitter()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//move up
for (int i = 0; i < thumbs.Count; i++)
{
AppiumWebElement thumb = thumbs[i];
int border = i == 0 ? 0 : thumbs[i - 1].Rect.Bottom;
Move(thumb, border, false, false);
Assert.IsTrue(thumb.Rect.Top - border <= moveStep);
Assert.IsTrue(thumb.Rect.Right > border);
}
//move down
for (int i = thumbs.Count - 1; i >= 0; i--)
{
AppiumWebElement thumb = thumbs[i];
int border = i == thumbs.Count - 1 ? Screen.PrimaryScreen.WorkingArea.Bottom : thumbs[i + 1].Rect.Top;
Move(thumb, border, true, false);
Assert.IsTrue(border - thumb.Rect.Bottom <= moveStep);
Assert.IsTrue(thumb.Rect.Top < border);
}
//move left
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.Y;
Move(thumb, 0, false, true);
int actual = thumb.Rect.Y;
Assert.AreEqual(expected, actual);
}
//move right
foreach (AppiumWebElement thumb in thumbs)
{
int expected = thumb.Rect.Y;
Move(thumb, Screen.PrimaryScreen.WorkingArea.Right, true, true);
int actual = thumb.Rect.Y;
Assert.AreEqual(expected, actual);
}
}
[TestMethod]
public void CreateSplitter()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WaitSeconds(2);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(3, zones.Count, "Zones count invalid");
const int defaultSpacing = 16;
int splitPos = zones[0].Rect.Y + zones[0].Rect.Height / 2;
new Actions(session).MoveToElement(zones[0]).Click().Perform();
zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
//check splitted zone
Assert.AreEqual(zones[0].Rect.Top, defaultSpacing);
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - splitPos + defaultSpacing / 2) <= 2);
Assert.IsTrue(Math.Abs(zones[3].Rect.Top - splitPos - defaultSpacing / 2) <= 2);
Assert.AreEqual(zones[3].Rect.Bottom, Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing);
}
[TestMethod]
public void TestSplitterShiftAfterCreation()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WaitSeconds(2);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(3, zones.Count, "Zones count invalid");
const int defaultSpacing = 16;
//create first split
int firstSplitPos = zones[0].Rect.Y + zones[0].Rect.Height / 4;
new Actions(session).MoveToElement(zones[0]).MoveByOffset(0, -(zones[0].Rect.Height / 4)).Click().Perform();
zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
Assert.AreEqual(zones[0].Rect.Top, defaultSpacing);
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - firstSplitPos + defaultSpacing / 2) <= 2);
Assert.IsTrue(Math.Abs(zones[3].Rect.Top - firstSplitPos - defaultSpacing / 2) <= 2);
Assert.AreEqual(zones[3].Rect.Bottom, Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing);
//create second split
int secondSplitPos = zones[3].Rect.Y + zones[3].Rect.Height / 2;
int expectedTop = zones[3].Rect.Top;
new Actions(session).MoveToElement(zones[3]).Click().Perform();
zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(5, zones.Count);
//check first split on same position
Assert.AreEqual(zones[0].Rect.Top, defaultSpacing);
Assert.IsTrue(Math.Abs(zones[0].Rect.Bottom - firstSplitPos + defaultSpacing / 2) <= 2);
//check second split
Assert.AreEqual(zones[3].Rect.Top, expectedTop);
Assert.IsTrue(Math.Abs(zones[3].Rect.Bottom - secondSplitPos + defaultSpacing / 2) <= 2);
Assert.IsTrue(Math.Abs(zones[4].Rect.Top - secondSplitPos - defaultSpacing / 2) <= 2);
Assert.AreEqual(zones[4].Rect.Bottom, Screen.PrimaryScreen.Bounds.Bottom - defaultSpacing);
}
[TestMethod]
public void CreateSplitterWithShiftPressed()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(2, thumbs.Count);
new Actions(session).MoveToElement(thumbs[0]).MoveByOffset(-100, 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
Assert.AreEqual(3, gridEditor.FindElementsByClassName("Thumb").Count);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
//check that zone was splitted vertically
Assert.AreEqual(zones[0].Rect.Height, zones[1].Rect.Height);
Assert.AreEqual(zones[1].Rect.Height, zones[2].Rect.Height);
Assert.AreEqual(zones[2].Rect.Height, zones[3].Rect.Height);
}
[TestMethod]
public void CreateSplitterWithShiftPressedFocusOnGridEditor()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(2, thumbs.Count);
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-100, 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
Assert.AreEqual(3, gridEditor.FindElementsByClassName("Thumb").Count);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Assert.AreEqual(4, zones.Count);
//check that zone was splitted vertically
Assert.AreEqual(zones[0].Rect.Height, zones[1].Rect.Height);
Assert.AreEqual(zones[1].Rect.Height, zones[2].Rect.Height);
Assert.AreEqual(zones[2].Rect.Height, zones[3].Rect.Height);
}
[TestMethod]
public void MoveHorizontallyWithLimiter()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//create new zones
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-30, 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(4, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(3, thumbs.Count);
//move thumbs
AppiumWebElement limiter = gridEditor.FindElementsByClassName("Thumb")[0];
AppiumWebElement movable = gridEditor.FindElementsByClassName("Thumb")[1];
Move(movable, 0, false, true);
Assert.IsTrue(movable.Rect.X > limiter.Rect.X);
Assert.IsTrue(movable.Rect.X - limiter.Rect.X < movable.Rect.Width);
Move(limiter, limiter.Rect.X - (limiter.Rect.X / 2), false, true);
Move(movable, 0, false, true);
Assert.IsTrue(movable.Rect.X > limiter.Rect.X);
Assert.IsTrue(movable.Rect.X - limiter.Rect.X < movable.Rect.Width);
}
[TestMethod]
public void MoveVerticallyWithLimiter()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
Assert.AreEqual(3, session.FindElementsByClassName("GridZone").Count);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(2, thumbs.Count);
//create new zones
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(0, -(thumbs[0].Rect.Y / 2))
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(4, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(3, thumbs.Count);
//move thumbs
AppiumWebElement limiter = gridEditor.FindElementsByClassName("Thumb")[0];
AppiumWebElement movable = gridEditor.FindElementsByClassName("Thumb")[1];
Move(movable, 0, false, false);
Assert.IsTrue(movable.Rect.Y > limiter.Rect.Y);
Assert.IsTrue(movable.Rect.Y - limiter.Rect.Y < movable.Rect.Height);
Move(limiter, limiter.Rect.Y - (limiter.Rect.Y / 2), false, false, -5);
Move(movable, 0, false, false);
Assert.IsTrue(movable.Rect.Y > limiter.Rect.Y);
Assert.IsTrue(movable.Rect.Y - limiter.Rect.Y < movable.Rect.Height);
}
[TestMethod]
public void MergeZones()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
Assert.AreEqual(3, zones.Count);
Assert.AreEqual(2, thumbs.Count);
Move(zones[0], thumbs[0].Rect.X + thumbs[0].Rect.Width + 10, true, true, -(zones[0].Rect.Height / 2) + 10);
WindowsElement mergeButton = session.FindElementByName("Merge zones");
Assert.IsNotNull(mergeButton, "Cannot merge: no merge button");
new Actions(session).Click(mergeButton).Perform();
Assert.AreEqual(2, session.FindElementsByClassName("GridZone").Count);
Assert.AreEqual(1, gridEditor.FindElementsByClassName("Thumb").Count);
}
[TestMethod]
public void MoveAfterMerge()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
WindowsElement gridEditor = session.FindElementByClassName("GridEditor");
Assert.IsNotNull(gridEditor);
ReadOnlyCollection<AppiumWebElement> thumbs = gridEditor.FindElementsByClassName("Thumb");
//create new zones
new Actions(session).MoveToElement(thumbs[0]).Click().MoveByOffset(-(thumbs[0].Rect.X / 2), 0)
.KeyDown(OpenQA.Selenium.Keys.Shift).Click().KeyUp(OpenQA.Selenium.Keys.Shift)
.Perform();
thumbs = gridEditor.FindElementsByClassName("Thumb");
//merge zones
ReadOnlyCollection<WindowsElement> zones = session.FindElementsByClassName("GridZone");
Move(zones[0], thumbs[0].Rect.X + thumbs[0].Rect.Width + 10, true, true, -(zones[0].Rect.Height / 2) + 10);
WindowsElement mergeButton = session.FindElementByName("Merge zones");
Assert.IsNotNull(mergeButton, "Cannot merge: no merge button");
new Actions(session).Click(mergeButton).Perform();
//move thumb
AppiumWebElement thumb = thumbs[1]; //thumb from merged zone is still present
Move(thumb, 0, false, true);
Assert.IsTrue(thumb.Rect.Left <= moveStep);
Assert.IsTrue(thumb.Rect.Right > 0);
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
return;
ResetSettings();
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenTemplates();
}
[ClassCleanup]
public static void ClassCleanup()
{
CloseEditor();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
}
[TestCleanup]
public void TestCleanup()
{
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
Assert.IsNotNull(cancelButton);
new Actions(session).MoveToElement(cancelButton).Click().Perform();
}
}
}

View File

@@ -13,9 +13,9 @@ namespace PowerToysTests
File.Delete(_zoneSettingsPath);
}
void RemoveSettingsFolder()
{
Directory.Delete(_settingsFolderPath, true);
void RemoveSettingsFolder()
{
Directory.Delete(_settingsFolderPath, true);
}
void CreateEmptySettingsFile()
@@ -48,56 +48,56 @@ namespace PowerToysTests
File.WriteAllText(_zoneSettingsPath, zoneSettings);
}
void CreateCroppedSettingsFile()
{
void CreateCroppedSettingsFile()
{
string zoneSettings = "{\"app-zone-history\":[],\"devices\":[],\"custom-zone-sets\":[{\"uuid\":\"{8BEC7183-C90E-4D41-AD1C-1AC2BC4760BA}\",\"name\":\"";
File.WriteAllText(_zoneSettingsPath, zoneSettings);
File.WriteAllText(_zoneSettingsPath, zoneSettings);
}
void TestEditorOpened()
{
WindowsElement errorMessage = null;
try
{
errorMessage = WaitElementByName("FancyZones Editor Exception Handler");
if (errorMessage != null)
{
errorMessage.FindElementByName("OK").Click();
}
void TestEditorOpened()
{
WindowsElement errorMessage = null;
try
{
errorMessage = WaitElementByName("FancyZones Editor Exception Handler");
if (errorMessage != null)
{
errorMessage.FindElementByName("OK").Click();
}
}
catch (OpenQA.Selenium.WebDriverException)
{
//no error message, it's ok
}
try
{
editorWindow = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
}
{
//no error message, it's ok
}
try
{
editorWindow = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
}
catch (OpenQA.Selenium.WebDriverException)
{
}
Assert.IsNotNull(editorWindow);
Assert.IsNull(errorMessage);
{
}
Assert.IsNotNull(editorWindow);
Assert.IsNull(errorMessage);
}
void OpenEditorBySettingsButton()
{
OpenSettings();
void OpenEditorBySettingsButton()
{
OpenSettings();
OpenFancyZonesSettings();
WindowsElement editorButton = session.FindElementByXPath("//Button[@Name=\"Edit zones\"]");
Assert.IsNotNull(editorButton);
editorButton.Click();
TestEditorOpened();
TestEditorOpened();
}
void OpenEditorByHotkey()
{
void OpenEditorByHotkey()
{
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
TestEditorOpened();
TestEditorOpened();
}
[TestMethod]
@@ -111,15 +111,15 @@ namespace PowerToysTests
public void OpenEditorBySettingsButtonNoSettingsFolder()
{
/*
if (isPowerToysLaunched)
{
ExitPowerToys();
if (isPowerToysLaunched)
{
ExitPowerToys();
}
RemoveSettingsFolder();
LaunchPowerToys();
*/
RemoveSettingsFolder();
RemoveSettingsFolder();
OpenEditorBySettingsButton();
}
@@ -156,33 +156,33 @@ namespace PowerToysTests
{
CreateInvalidSettingsFile();
OpenEditorBySettingsButton();
}
}
[TestMethod]
public void OpenEditorBySettingsButtonCroppedSettings()
{
CreateCroppedSettingsFile();
OpenEditorBySettingsButton();
}
[TestMethod]
}
[TestMethod]
public void OpenEditorByHotkeyNoSettings()
{
RemoveSettingsFile();
OpenEditorByHotkey();
}
[TestMethod]
}
[TestMethod]
public void OpenEditorByHotkeyNoSettingsFolder()
{
/*
if (isPowerToysLaunched)
{
ExitPowerToys();
if (isPowerToysLaunched)
{
ExitPowerToys();
}
RemoveSettingsFolder();
LaunchPowerToys();
*/
LaunchPowerToys();
*/
RemoveSettingsFolder();
OpenEditorByHotkey();
}
@@ -233,7 +233,7 @@ namespace PowerToysTests
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
if (session == null)
return;
ResetDefaultFancyZonesSettings(true);
@@ -241,25 +241,25 @@ namespace PowerToysTests
[ClassCleanup]
public static void ClassCleanup()
{
ExitPowerToys();
{
ExitPowerToys();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
{
}
[TestCleanup]
public void TestCleanup()
{
CloseEditor();
if (!Directory.Exists(_settingsFolderPath))
{
Directory.CreateDirectory(_settingsFolderPath);
CloseEditor();
if (!Directory.Exists(_settingsFolderPath))
{
Directory.CreateDirectory(_settingsFolderPath);
}
}
}

View File

@@ -7,68 +7,68 @@ namespace PowerToysTests
[TestClass]
public class FancyZonesEditorTemplatesApplyTests : FancyZonesEditor
{
private void ApplyLayout(string tabName)
{
string elementXPath = "//Text[@Name=\"" + tabName + "\"]";
session.FindElementByXPath(elementXPath).Click();
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
try
{
Assert.IsNull(session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]"));
}
catch (OpenQA.Selenium.WebDriverException)
{
//editor was closed as expected
}
private void ApplyLayout(string tabName)
{
string elementXPath = "//Text[@Name=\"" + tabName + "\"]";
session.FindElementByXPath(elementXPath).Click();
session.FindElementByAccessibilityId("ApplyTemplateButton").Click();
try
{
Assert.IsNull(session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]"));
}
catch (OpenQA.Selenium.WebDriverException)
{
//editor was closed as expected
}
}
private void CheckSettingsLayout(string expectedLayout)
{
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(expectedLayout, settings["devices"][0]["active-zoneset"]["type"]);
private void CheckSettingsLayout(string expectedLayout)
{
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual(expectedLayout, settings["devices"][0]["active-zoneset"]["type"]);
}
[TestMethod]
public void ApplyFocus()
{
ApplyLayout("Focus");
CheckSettingsLayout("focus");
}
public void ApplyFocus()
{
ApplyLayout("Focus");
CheckSettingsLayout("focus");
}
[TestMethod]
public void ApplyColumns()
{
ApplyLayout("Columns");
CheckSettingsLayout("columns");
}
public void ApplyColumns()
{
ApplyLayout("Columns");
CheckSettingsLayout("columns");
}
[TestMethod]
public void ApplyRows()
{
ApplyLayout("Rows");
CheckSettingsLayout("rows");
}
public void ApplyRows()
{
ApplyLayout("Rows");
CheckSettingsLayout("rows");
}
[TestMethod]
public void ApplyGrid()
{
ApplyLayout("Grid");
CheckSettingsLayout("grid");
}
public void ApplyGrid()
{
ApplyLayout("Grid");
CheckSettingsLayout("grid");
}
[TestMethod]
public void ApplyPriorityGrid()
{
ApplyLayout("Priority Grid");
CheckSettingsLayout("priority-grid");
public void ApplyPriorityGrid()
{
ApplyLayout("Priority Grid");
CheckSettingsLayout("priority-grid");
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
if (session == null)
return;
ResetDefaultFancyZonesSettings(true);
@@ -77,23 +77,23 @@ namespace PowerToysTests
[ClassCleanup]
public static void ClassCleanup()
{
CloseSettings();
CloseSettings();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
if (session == null)
return;
OpenEditor();
OpenTemplates();
{
if (session == null)
return;
OpenEditor();
OpenTemplates();
}
[TestCleanup]
public void TestCleanup()
{
{
}
}
}

View File

@@ -1,7 +1,7 @@
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
namespace PowerToysTests
@@ -9,155 +9,155 @@ namespace PowerToysTests
[TestClass]
public class FancyZonesEditorTemplatesEditTests : FancyZonesEditor
{
private void ChangeLayout()
{
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_TitleBar")).MoveByOffset(0, -50).Click().Perform();
private void ChangeLayout()
{
new Actions(session).MoveToElement(session.FindElementByAccessibilityId("PART_TitleBar")).MoveByOffset(0, -50).Click().Perform();
}
private void CancelTest()
{
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
new Actions(session).MoveToElement(cancelButton).Click().Perform();
WaitSeconds(1);
Assert.AreEqual(_defaultZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
private void CancelTest()
{
WindowsElement cancelButton = session.FindElementByXPath("//Window[@Name=\"FancyZones Editor\"]/Window/Button[@Name=\"Cancel\"]");
new Actions(session).MoveToElement(cancelButton).Click().Perform();
WaitSeconds(1);
Assert.AreEqual(_defaultZoneSettings, File.ReadAllText(_zoneSettingsPath), "Settings were changed");
}
private void SaveTest()
{
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual("Custom Layout 1", settings["custom-zone-sets"][0]["name"]);
Assert.AreEqual(settings["custom-zone-sets"][0]["uuid"], settings["devices"][0]["active-zoneset"]["uuid"]);
private void SaveTest()
{
new Actions(session).MoveToElement(session.FindElementByName("Save and apply")).Click().Perform();
WaitSeconds(1);
JObject settings = JObject.Parse(File.ReadAllText(_zoneSettingsPath));
Assert.AreEqual("Custom Layout 1", settings["custom-zone-sets"][0]["name"]);
Assert.AreEqual(settings["custom-zone-sets"][0]["uuid"], settings["devices"][0]["active-zoneset"]["uuid"]);
}
[TestMethod]
public void EditFocusCancel()
{
OpenCreatorWindow("Focus", "Custom layout creator", "EditTemplateButton");
ZoneCountTest(3, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(4, 0);
CancelTest();
}
[TestMethod]
public void EditColumnsCancel()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditRowsCancel()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditGridCancel()
{
OpenCreatorWindow("Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditPriorityGridCancel()
{
OpenCreatorWindow("Priority Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
public void EditFocusCancel()
{
OpenCreatorWindow("Focus", "Custom layout creator", "EditTemplateButton");
ZoneCountTest(3, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(4, 0);
CancelTest();
}
[TestMethod]
public void EditFocusSave()
{
OpenCreatorWindow("Focus", "Custom layout creator", "EditTemplateButton");
ZoneCountTest(3, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(4, 0);
SaveTest();
}
public void EditColumnsCancel()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditColumnsSave()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
public void EditRowsCancel()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditRowsSave()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
public void EditGridCancel()
{
OpenCreatorWindow("Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditGridSave()
{
OpenCreatorWindow("Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
public void EditPriorityGridCancel()
{
OpenCreatorWindow("Priority Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
CancelTest();
}
[TestMethod]
public void EditPriorityGridSave()
{
OpenCreatorWindow("Priority Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
public void EditFocusSave()
{
OpenCreatorWindow("Focus", "Custom layout creator", "EditTemplateButton");
ZoneCountTest(3, 0);
session.FindElementByAccessibilityId("newZoneButton").Click();
ZoneCountTest(4, 0);
SaveTest();
}
[TestMethod]
public void EditColumnsSave()
{
OpenCreatorWindow("Columns", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
[TestMethod]
public void EditRowsSave()
{
OpenCreatorWindow("Rows", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
[TestMethod]
public void EditGridSave()
{
OpenCreatorWindow("Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
[TestMethod]
public void EditPriorityGridSave()
{
OpenCreatorWindow("Priority Grid", "Custom table layout creator", "EditTemplateButton");
ZoneCountTest(0, 3);
ChangeLayout();
ZoneCountTest(0, 4);
SaveTest();
}
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
Setup(context, false);
if (session == null)
if (session == null)
return;
ResetDefaultFancyZonesSettings(false);
@@ -167,41 +167,41 @@ namespace PowerToysTests
[ClassCleanup]
public static void ClassCleanup()
{
CloseSettings();
CloseSettings();
TearDown();
}
[TestInitialize]
public void TestInitialize()
{
if (session == null)
return;
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenTemplates();
{
if (session == null)
return;
if (!isPowerToysLaunched)
{
LaunchPowerToys();
}
OpenEditor();
OpenTemplates();
}
[TestCleanup]
public void TestCleanup()
{
//Close editor
try
{
if (editorWindow != null)
{
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
}
try
{
if (editorWindow != null)
{
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
}
}
catch (OpenQA.Selenium.WebDriverException)
{
//editor has already closed
{
//editor has already closed
}
ResetDefaultZoneSettings(false);
ResetDefaultZoneSettings(false);
}
}
}

View File

@@ -1,104 +1,104 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
using System;
using OpenQA.Selenium.Interactions;
using System;
namespace PowerToysTests
{
public class FancyZonesEditor : PowerToysSession
{
protected static WindowsElement editorWindow;
protected static void ResetSettings()
{
public class FancyZonesEditor : PowerToysSession
{
protected static WindowsElement editorWindow;
protected static void ResetSettings()
{
ResetDefaultFancyZonesSettings(false);
ResetDefaultZoneSettings(true);
}
protected static void OpenEditor()
{
try
{
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
WaitSeconds(2);
//editorWindow = WaitElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
editorWindow = WaitElementByName("FancyZones Editor");
//may not find editor by name in 0.16.1
//editorWindow = WaitElementByAccessibilityId("MainWindow1");
Assert.IsNotNull(editorWindow, "Couldn't find editor window");
}
ResetDefaultZoneSettings(true);
}
protected static void OpenEditor()
{
try
{
new Actions(session).KeyDown(OpenQA.Selenium.Keys.Command).SendKeys("`").KeyUp(OpenQA.Selenium.Keys.Command).Perform();
WaitSeconds(2);
//editorWindow = WaitElementByXPath("//Window[@Name=\"FancyZones Editor\"]");
editorWindow = WaitElementByName("FancyZones Editor");
//may not find editor by name in 0.16.1
//editorWindow = WaitElementByAccessibilityId("MainWindow1");
Assert.IsNotNull(editorWindow, "Couldn't find editor window");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
protected static void CloseEditor()
{
try
{
if (editorWindow != null)
{
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
}
{
Console.WriteLine(ex.Message);
}
}
protected static void CloseEditor()
{
try
{
if (editorWindow != null)
{
editorWindow.SendKeys(OpenQA.Selenium.Keys.Alt + OpenQA.Selenium.Keys.F4);
}
}
catch (OpenQA.Selenium.WebDriverException)
{
//editor has been already closed
}
}
protected static void OpenCustomLayouts()
{
try
{
WindowsElement customsTab = session.FindElementByName("Custom");
customsTab.Click();
string isSelected = customsTab.GetAttribute("SelectionItem.IsSelected");
Assert.AreEqual("True", isSelected, "Custom tab cannot be opened");
}
{
//editor has been already closed
}
}
protected static void OpenCustomLayouts()
{
try
{
WindowsElement customsTab = session.FindElementByName("Custom");
customsTab.Click();
string isSelected = customsTab.GetAttribute("SelectionItem.IsSelected");
Assert.AreEqual("True", isSelected, "Custom tab cannot be opened");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
protected static void OpenTemplates()
{
try
{
WindowsElement templatesTab = session.FindElementByName("Templates");
templatesTab.Click();
string isSelected = templatesTab.GetAttribute("SelectionItem.IsSelected");
Assert.AreEqual("True", isSelected, "Templates tab cannot be opened");
}
{
Console.WriteLine(ex.Message);
}
}
protected static void OpenTemplates()
{
try
{
WindowsElement templatesTab = session.FindElementByName("Templates");
templatesTab.Click();
string isSelected = templatesTab.GetAttribute("SelectionItem.IsSelected");
Assert.AreEqual("True", isSelected, "Templates tab cannot be opened");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
protected static void OpenCreatorWindow(string tabName, string creatorWindowName, string buttonId = "EditCustomButton")
{
try
{
string elementXPath = "//Text[@Name=\"" + tabName + "\"]";
WaitElementByXPath(elementXPath).Click();
WaitElementByAccessibilityId(buttonId).Click();
WindowsElement creatorWindow = WaitElementByName(creatorWindowName);
Assert.IsNotNull(creatorWindow, "Creator window didn't open");
}
{
Console.WriteLine(ex.Message);
}
}
protected static void OpenCreatorWindow(string tabName, string creatorWindowName, string buttonId = "EditCustomButton")
{
try
{
string elementXPath = "//Text[@Name=\"" + tabName + "\"]";
WaitElementByXPath(elementXPath).Click();
WaitElementByAccessibilityId(buttonId).Click();
WindowsElement creatorWindow = WaitElementByName(creatorWindowName);
Assert.IsNotNull(creatorWindow, "Creator window didn't open");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
protected void ZoneCountTest(int canvasZoneCount, int gridZoneCount)
{
Assert.AreEqual(canvasZoneCount, session.FindElementsByClassName("CanvasZone").Count);
Assert.AreEqual(gridZoneCount, session.FindElementsByClassName("GridZone").Count);
}
}
{
Console.WriteLine(ex.Message);
}
}
protected void ZoneCountTest(int canvasZoneCount, int gridZoneCount)
{
Assert.AreEqual(canvasZoneCount, session.FindElementsByClassName("CanvasZone").Count);
Assert.AreEqual(gridZoneCount, session.FindElementsByClassName("GridZone").Count);
}
}
}

View File

@@ -1,5 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Interactions;
@@ -34,12 +34,12 @@ namespace PowerToysTests
WindowsElement pt = session.FindElementByName("PowerToys");
Assert.IsNotNull(pt);
new Actions(session).MoveToElement(pt).ContextClick().Perform();
//open settings
WaitElementByXPath("//MenuItem[@Name=\"Settings\"]").Click();
//check settings window opened
new Actions(session).MoveToElement(pt).ContextClick().Perform();
//open settings
WaitElementByXPath("//MenuItem[@Name=\"Settings\"]").Click();
//check settings window opened
WindowsElement settingsWindow = WaitElementByName("PowerToys Settings");
Assert.IsNotNull(settingsWindow);
@@ -58,17 +58,17 @@ namespace PowerToysTests
AppiumWebElement powerToys = overflowArea.FindElementByName("PowerToys");
Assert.IsNotNull(powerToys);
new Actions(session).MoveToElement(powerToys).ContextClick().Perform();
//exit
WaitElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
//check PowerToys exited
new Actions(session).MoveToElement(powerToys).ContextClick().Perform();
//exit
WaitElementByXPath("//MenuItem[@Name=\"Exit\"]").Click();
//check PowerToys exited
powerToys = null;
try
{
notificationOverflow = session.FindElementByName("Notification Overflow");
overflowArea = notificationOverflow.FindElementByName("Overflow Notification Area");
notificationOverflow = session.FindElementByName("Notification Overflow");
overflowArea = notificationOverflow.FindElementByName("Overflow Notification Area");
powerToys = overflowArea.FindElementByName("PowerToys");
}
catch (OpenQA.Selenium.WebDriverException)
@@ -95,7 +95,7 @@ namespace PowerToysTests
[TestInitialize]
public void TestInitialize()
{
if (session == null)
if (session == null)
return;
isSettingsOpened = false;
@@ -108,8 +108,8 @@ namespace PowerToysTests
if (isSettingsOpened)
{
CloseSettings();
}
}
if (isTrayOpened)
{
trayButton.Click();