committed by
GitHub
18 changed files with 659 additions and 52 deletions
@ -0,0 +1,25 @@ |
|||||
|
<Window xmlns="https://github.com/avaloniaui" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
x:Class="IntegrationTestApp.ShowWindowTest" |
||||
|
Name="SecondaryWindow" |
||||
|
Title="Show Window Test"> |
||||
|
<Grid ColumnDefinitions="Auto,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto"> |
||||
|
<Label Grid.Column="0" Grid.Row="1">Client Size</Label> |
||||
|
<TextBox Name="ClientSize" Grid.Column="1" Grid.Row="1" IsReadOnly="True"/> |
||||
|
|
||||
|
<Label Grid.Column="0" Grid.Row="2">Frame Size</Label> |
||||
|
<TextBox Name="FrameSize" Grid.Column="1" Grid.Row="2" IsReadOnly="True"/> |
||||
|
|
||||
|
<Label Grid.Column="0" Grid.Row="3">Position</Label> |
||||
|
<TextBox Name="Position" Grid.Column="1" Grid.Row="3" IsReadOnly="True"/> |
||||
|
|
||||
|
<Label Grid.Column="0" Grid.Row="4">Owner Rect</Label> |
||||
|
<TextBox Name="OwnerRect" Grid.Column="1" Grid.Row="4" IsReadOnly="True"/> |
||||
|
|
||||
|
<Label Grid.Column="0" Grid.Row="5">Screen Rect</Label> |
||||
|
<TextBox Name="ScreenRect" Grid.Column="1" Grid.Row="5" IsReadOnly="True"/> |
||||
|
|
||||
|
<Label Grid.Column="0" Grid.Row="6">Scaling</Label> |
||||
|
<TextBox Name="Scaling" Grid.Column="1" Grid.Row="6" IsReadOnly="True"/> |
||||
|
</Grid> |
||||
|
</Window> |
||||
@ -0,0 +1,38 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Interactivity; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using Avalonia.Rendering; |
||||
|
|
||||
|
namespace IntegrationTestApp |
||||
|
{ |
||||
|
public class ShowWindowTest : Window |
||||
|
{ |
||||
|
public ShowWindowTest() |
||||
|
{ |
||||
|
InitializeComponent(); |
||||
|
} |
||||
|
|
||||
|
private void InitializeComponent() |
||||
|
{ |
||||
|
AvaloniaXamlLoader.Load(this); |
||||
|
} |
||||
|
|
||||
|
protected override void OnOpened(EventArgs e) |
||||
|
{ |
||||
|
base.OnOpened(e); |
||||
|
this.GetControl<TextBox>("ClientSize").Text = $"{Width}, {Height}"; |
||||
|
this.GetControl<TextBox>("FrameSize").Text = $"{FrameSize}"; |
||||
|
this.GetControl<TextBox>("Position").Text = $"{Position}"; |
||||
|
this.GetControl<TextBox>("ScreenRect").Text = $"{Screens.ScreenFromVisual(this)?.WorkingArea}"; |
||||
|
this.GetControl<TextBox>("Scaling").Text = $"{PlatformImpl?.DesktopScaling}"; |
||||
|
|
||||
|
if (Owner is not null) |
||||
|
{ |
||||
|
var ownerRect = this.GetControl<TextBox>("OwnerRect"); |
||||
|
var owner = (Window)Owner; |
||||
|
ownerRect.Text = $"{owner.Position}, {owner.FrameSize}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,125 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using Avalonia.Controls; |
||||
|
using OpenQA.Selenium.Appium; |
||||
|
using Xunit; |
||||
|
using Xunit.Sdk; |
||||
|
|
||||
|
namespace Avalonia.IntegrationTests.Appium |
||||
|
{ |
||||
|
[Collection("Default")] |
||||
|
public class WindowTests |
||||
|
{ |
||||
|
private readonly AppiumDriver<AppiumWebElement> _session; |
||||
|
|
||||
|
public WindowTests(TestAppFixture fixture) |
||||
|
{ |
||||
|
_session = fixture.Session; |
||||
|
|
||||
|
var tabs = _session.FindElementByAccessibilityId("MainTabs"); |
||||
|
var tab = tabs.FindElementByName("Window"); |
||||
|
tab.Click(); |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[MemberData(nameof(StartupLocationData))] |
||||
|
public void StartupLocation(PixelSize? size, ShowWindowMode mode, WindowStartupLocation location) |
||||
|
{ |
||||
|
using var window = OpenWindow(size, mode, location); |
||||
|
var clientSize = Size.Parse(_session.FindElementByAccessibilityId("ClientSize").Text); |
||||
|
var frameSize = Size.Parse(_session.FindElementByAccessibilityId("FrameSize").Text); |
||||
|
var position = PixelPoint.Parse(_session.FindElementByAccessibilityId("Position").Text); |
||||
|
var screenRect = PixelRect.Parse(_session.FindElementByAccessibilityId("ScreenRect").Text); |
||||
|
var scaling = double.Parse(_session.FindElementByAccessibilityId("Scaling").Text); |
||||
|
|
||||
|
Assert.True(frameSize.Width >= clientSize.Width, "Expected frame width >= client width."); |
||||
|
Assert.True(frameSize.Height > clientSize.Height, "Expected frame height > client height."); |
||||
|
|
||||
|
var frameRect = new PixelRect(position, PixelSize.FromSize(frameSize, scaling)); |
||||
|
|
||||
|
switch (location) |
||||
|
{ |
||||
|
case WindowStartupLocation.CenterScreen: |
||||
|
{ |
||||
|
var expected = screenRect.CenterRect(frameRect); |
||||
|
AssertCloseEnough(expected.Position, frameRect.Position); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static TheoryData<PixelSize?, ShowWindowMode, WindowStartupLocation> StartupLocationData() |
||||
|
{ |
||||
|
var sizes = new PixelSize?[] { null, new PixelSize(400, 300) }; |
||||
|
var data = new TheoryData<PixelSize?, ShowWindowMode, WindowStartupLocation>(); |
||||
|
|
||||
|
foreach (var size in sizes) |
||||
|
{ |
||||
|
foreach (var mode in Enum.GetValues<ShowWindowMode>()) |
||||
|
{ |
||||
|
foreach (var location in Enum.GetValues<WindowStartupLocation>()) |
||||
|
{ |
||||
|
if (!(location == WindowStartupLocation.CenterOwner && mode == ShowWindowMode.NonOwned)) |
||||
|
{ |
||||
|
data.Add(size, mode, location); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
private static void AssertCloseEnough(PixelPoint expected, PixelPoint actual) |
||||
|
{ |
||||
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
||||
|
{ |
||||
|
// On win32, accurate frame information cannot be obtained until a window is shown but
|
||||
|
// WindowStartupLocation needs to be calculated before the window is shown, meaning that
|
||||
|
// the position of a centered window can be off by a bit. From initial testing, looks
|
||||
|
// like this shouldn't be more than 10 pixels.
|
||||
|
if (Math.Abs(expected.X - actual.X) > 10) |
||||
|
throw new EqualException(expected, actual); |
||||
|
if (Math.Abs(expected.Y - actual.Y) > 10) |
||||
|
throw new EqualException(expected, actual); |
||||
|
} |
||||
|
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) |
||||
|
{ |
||||
|
if (Math.Abs(expected.X - actual.X) > 15) |
||||
|
throw new EqualException(expected, actual); |
||||
|
if (Math.Abs(expected.Y - actual.Y) > 15) |
||||
|
throw new EqualException(expected, actual); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Assert.Equal(expected, actual); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private IDisposable OpenWindow(PixelSize? size, ShowWindowMode mode, WindowStartupLocation location) |
||||
|
{ |
||||
|
var sizeTextBox = _session.FindElementByAccessibilityId("ShowWindowSize"); |
||||
|
var modeComboBox = _session.FindElementByAccessibilityId("ShowWindowMode"); |
||||
|
var locationComboBox = _session.FindElementByAccessibilityId("ShowWindowLocation"); |
||||
|
var showButton = _session.FindElementByAccessibilityId("ShowWindow"); |
||||
|
|
||||
|
if (size.HasValue) |
||||
|
sizeTextBox.SendKeys($"{size.Value.Width}, {size.Value.Height}"); |
||||
|
|
||||
|
modeComboBox.Click(); |
||||
|
_session.FindElementByName(mode.ToString()).SendClick(); |
||||
|
|
||||
|
locationComboBox.Click(); |
||||
|
_session.FindElementByName(location.ToString()).SendClick(); |
||||
|
|
||||
|
return showButton.OpenWindowWithClick(); |
||||
|
} |
||||
|
|
||||
|
public enum ShowWindowMode |
||||
|
{ |
||||
|
NonOwned, |
||||
|
Owned, |
||||
|
Modal |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,210 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading; |
||||
|
using Avalonia.Controls; |
||||
|
using OpenQA.Selenium; |
||||
|
using OpenQA.Selenium.Appium; |
||||
|
using OpenQA.Selenium.Interactions; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Avalonia.IntegrationTests.Appium |
||||
|
{ |
||||
|
[Collection("Default")] |
||||
|
public class WindowTests_MacOS |
||||
|
{ |
||||
|
private readonly AppiumDriver<AppiumWebElement> _session; |
||||
|
|
||||
|
public WindowTests_MacOS(TestAppFixture fixture) |
||||
|
{ |
||||
|
_session = fixture.Session; |
||||
|
|
||||
|
var tabs = _session.FindElementByAccessibilityId("MainTabs"); |
||||
|
var tab = tabs.FindElementByName("Window"); |
||||
|
tab.Click(); |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void WindowOrder_Modal_Dialog_Stays_InFront_Of_Parent() |
||||
|
{ |
||||
|
var mainWindow = _session.FindElementByAccessibilityId("MainWindow"); |
||||
|
|
||||
|
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
mainWindow.Click(); |
||||
|
|
||||
|
var windows = _session.FindElements(By.XPath("XCUIElementTypeWindow")); |
||||
|
var mainWindowIndex = GetWindowOrder(windows, "MainWindow"); |
||||
|
var secondaryWindowIndex = GetWindowOrder(windows, "SecondaryWindow"); |
||||
|
|
||||
|
Assert.Equal(0, secondaryWindowIndex); |
||||
|
Assert.Equal(1, mainWindowIndex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void WindowOrder_Modal_Dialog_Stays_InFront_Of_Parent_When_Clicking_Resize_Grip() |
||||
|
{ |
||||
|
var mainWindow = FindWindow(_session, "MainWindow"); |
||||
|
|
||||
|
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
new Actions(_session) |
||||
|
.MoveToElement(mainWindow, 100, 1) |
||||
|
.ClickAndHold() |
||||
|
.Perform(); |
||||
|
|
||||
|
var windows = _session.FindElements(By.XPath("XCUIElementTypeWindow")); |
||||
|
var mainWindowIndex = GetWindowOrder(windows, "MainWindow"); |
||||
|
var secondaryWindowIndex = GetWindowOrder(windows, "SecondaryWindow"); |
||||
|
|
||||
|
new Actions(_session) |
||||
|
.MoveToElement(mainWindow, 100, 1) |
||||
|
.Release() |
||||
|
.Perform(); |
||||
|
|
||||
|
Assert.Equal(0, secondaryWindowIndex); |
||||
|
Assert.Equal(1, mainWindowIndex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void WindowOrder_Modal_Dialog_Stays_InFront_Of_Parent_When_In_Fullscreen() |
||||
|
{ |
||||
|
var mainWindow = FindWindow(_session, "MainWindow"); |
||||
|
var buttons = mainWindow.GetChromeButtons(); |
||||
|
|
||||
|
buttons.maximize.Click(); |
||||
|
|
||||
|
Thread.Sleep(500); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
var windows = _session.FindElements(By.XPath("XCUIElementTypeWindow")); |
||||
|
var mainWindowIndex = GetWindowOrder(windows, "MainWindow"); |
||||
|
var secondaryWindowIndex = GetWindowOrder(windows, "SecondaryWindow"); |
||||
|
|
||||
|
Assert.Equal(0, secondaryWindowIndex); |
||||
|
Assert.Equal(1, mainWindowIndex); |
||||
|
} |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
_session.FindElementByAccessibilityId("ExitFullscreen").Click(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void WindowOrder_Owned_Dialog_Stays_InFront_Of_Parent() |
||||
|
{ |
||||
|
var mainWindow = _session.FindElementByAccessibilityId("MainWindow"); |
||||
|
|
||||
|
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Owned, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
mainWindow.Click(); |
||||
|
|
||||
|
var windows = _session.FindElements(By.XPath("XCUIElementTypeWindow")); |
||||
|
var mainWindowIndex = GetWindowOrder(windows, "MainWindow"); |
||||
|
var secondaryWindowIndex = GetWindowOrder(windows, "SecondaryWindow"); |
||||
|
|
||||
|
Assert.Equal(0, secondaryWindowIndex); |
||||
|
Assert.Equal(1, mainWindowIndex); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void WindowOrder_NonOwned_Window_Does_Not_Stay_InFront_Of_Parent() |
||||
|
{ |
||||
|
var mainWindow = _session.FindElementByAccessibilityId("MainWindow"); |
||||
|
|
||||
|
using (OpenWindow(new PixelSize(1400, 100), ShowWindowMode.NonOwned, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
mainWindow.Click(); |
||||
|
|
||||
|
var windows = _session.FindElements(By.XPath("XCUIElementTypeWindow")); |
||||
|
var mainWindowIndex = GetWindowOrder(windows, "MainWindow"); |
||||
|
var secondaryWindowIndex = GetWindowOrder(windows, "SecondaryWindow"); |
||||
|
|
||||
|
Assert.Equal(1, secondaryWindowIndex); |
||||
|
Assert.Equal(0, mainWindowIndex); |
||||
|
|
||||
|
var sendToBack = _session.FindElementByAccessibilityId("SendToBack"); |
||||
|
sendToBack.Click(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void Parent_Window_Has_Disabled_ChromeButtons_When_Modal_Dialog_Shown() |
||||
|
{ |
||||
|
var window = FindWindow(_session, "MainWindow"); |
||||
|
var (closeButton, miniaturizeButton, zoomButton) = window.GetChromeButtons(); |
||||
|
|
||||
|
Assert.True(closeButton.Enabled); |
||||
|
Assert.True(zoomButton.Enabled); |
||||
|
Assert.True(miniaturizeButton.Enabled); |
||||
|
|
||||
|
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
Assert.False(closeButton.Enabled); |
||||
|
Assert.False(zoomButton.Enabled); |
||||
|
Assert.False(miniaturizeButton.Enabled); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[PlatformFact(TestPlatforms.MacOS)] |
||||
|
public void Minimize_Button_Is_Disabled_On_Modal_Dialog() |
||||
|
{ |
||||
|
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner)) |
||||
|
{ |
||||
|
var secondaryWindow = FindWindow(_session, "SecondaryWindow"); |
||||
|
var (closeButton, miniaturizeButton, zoomButton) = secondaryWindow.GetChromeButtons(); |
||||
|
|
||||
|
Assert.True(closeButton.Enabled); |
||||
|
Assert.True(zoomButton.Enabled); |
||||
|
Assert.False(miniaturizeButton.Enabled); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private IDisposable OpenWindow(PixelSize? size, ShowWindowMode mode, WindowStartupLocation location) |
||||
|
{ |
||||
|
var sizeTextBox = _session.FindElementByAccessibilityId("ShowWindowSize"); |
||||
|
var modeComboBox = _session.FindElementByAccessibilityId("ShowWindowMode"); |
||||
|
var locationComboBox = _session.FindElementByAccessibilityId("ShowWindowLocation"); |
||||
|
var showButton = _session.FindElementByAccessibilityId("ShowWindow"); |
||||
|
|
||||
|
if (size.HasValue) |
||||
|
sizeTextBox.SendKeys($"{size.Value.Width}, {size.Value.Height}"); |
||||
|
|
||||
|
modeComboBox.Click(); |
||||
|
_session.FindElementByName(mode.ToString()).SendClick(); |
||||
|
|
||||
|
locationComboBox.Click(); |
||||
|
_session.FindElementByName(location.ToString()).SendClick(); |
||||
|
|
||||
|
return showButton.OpenWindowWithClick(); |
||||
|
} |
||||
|
|
||||
|
private static int GetWindowOrder(IReadOnlyCollection<AppiumWebElement> elements, string identifier) |
||||
|
{ |
||||
|
return elements.TakeWhile(x => |
||||
|
x.FindElementByXPath("XCUIElementTypeWindow")?.GetAttribute("identifier") != identifier).Count(); |
||||
|
} |
||||
|
|
||||
|
private static AppiumWebElement FindWindow(AppiumDriver<AppiumWebElement> session, string identifier) |
||||
|
{ |
||||
|
var windows = session.FindElementsByXPath("XCUIElementTypeWindow"); |
||||
|
return windows.First(x => |
||||
|
x.FindElementsByXPath("XCUIElementTypeWindow") |
||||
|
.Any(y => y.GetAttribute("identifier") == identifier)); |
||||
|
} |
||||
|
|
||||
|
public enum ShowWindowMode |
||||
|
{ |
||||
|
NonOwned, |
||||
|
Owned, |
||||
|
Modal |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue