Browse Source

fix opennewwindow, share code between windowtests and macos window tests.

fixes/integration-tests-window-management
Dan Walmsley 3 years ago
parent
commit
aa0f481b6c
  1. 189
      tests/Avalonia.IntegrationTests.Appium/WindowTests.cs
  2. 197
      tests/Avalonia.IntegrationTests.Appium/WindowTestsBase.cs
  3. 94
      tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs
  4. 30
      tests/Avalonia.IntegrationTests.Appium/Wrappers/Element.cs
  5. 16
      tests/Avalonia.IntegrationTests.Appium/Wrappers/MacSession.cs
  6. 35
      tests/Avalonia.IntegrationTests.Appium/Wrappers/WindowElement.cs

189
tests/Avalonia.IntegrationTests.Appium/WindowTests.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Avalonia.Controls;
@ -9,24 +8,21 @@ using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Interactions;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Sdk;
namespace Avalonia.IntegrationTests.Appium
{
[Collection("Default")]
public class WindowTests
public class WindowTests : WindowTestsBase
{
private readonly ISession _session;
private readonly AppiumDriver<AppiumWebElement> _driver;
private readonly IWindowElement _mainWindow;
public WindowTests(DefaultAppFixture fixture)
public WindowTests(DefaultAppFixture fixture) : base (fixture.Session)
{
_session = fixture.Session;
_driver = fixture.Driver;
_mainWindow = _session.GetWindow("MainWindow");
var tab = _mainWindow.FindElementByName("Window");
var tab = MainWindow.FindElementByName("Window");
tab.Click();
}
@ -169,7 +165,7 @@ namespace Avalonia.IntegrationTests.Appium
public void ShowMode(ShowWindowMode mode)
{
using var window = OpenWindow(null, mode, WindowStartupLocation.Manual);
var windowState = _mainWindow.FindElementByAccessibilityId("CurrentWindowState");
var windowState = window.FindElementByAccessibilityId("CurrentWindowState");
var original = GetWindowInfo(window);
Assert.Equal("Normal", windowState.GetComboBoxValue());
@ -210,11 +206,13 @@ namespace Avalonia.IntegrationTests.Appium
[Fact]
public void TransparentWindow()
{
var showTransparentWindow = _mainWindow.FindElementByAccessibilityId("ShowTransparentWindow");
var showTransparentWindow = MainWindow.FindElementByAccessibilityId("ShowTransparentWindow");
showTransparentWindow.Click();
Thread.Sleep(1000);
var window = _mainWindow.FindElementByAccessibilityId("TransparentWindow");
var window = _session.GetWindow("TransparentWindow");
var screenshot = window.GetScreenshot();
window.Click();
@ -230,11 +228,11 @@ namespace Avalonia.IntegrationTests.Appium
[Fact]
public void TransparentPopup()
{
var showTransparentWindow = _mainWindow.FindElementByAccessibilityId("ShowTransparentPopup");
var showTransparentWindow = MainWindow.FindElementByAccessibilityId("ShowTransparentPopup");
showTransparentWindow.Click();
Thread.Sleep(1000);
var window = _mainWindow.FindElementByAccessibilityId("TransparentPopupBackground");
using var window = _session.GetWindow("TransparentPopupBackground");
var container = window.FindElementByAccessibilityId("PopupContainer");
var screenshot = container.GetScreenshot();
@ -300,168 +298,5 @@ namespace Avalonia.IntegrationTests.Appium
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 IWindowElement OpenWindow(
Size? size,
ShowWindowMode mode,
WindowStartupLocation location = WindowStartupLocation.Manual,
WindowState state = Controls.WindowState.Normal,
bool canResize = true)
{
var timer = new SplitTimer();
var elements = _mainWindow.GetChildren();
timer.SplitLog("getChildren");
if (size.HasValue)
{
var sizeTextBox = _mainWindow.FindElementByAccessibilityId("ShowWindowSize");
timer.SplitLog(nameof(sizeTextBox));
sizeTextBox.SendKeys($"{size.Value.Width}, {size.Value.Height}");
}
var modeComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowMode");
timer.SplitLog(nameof(modeComboBox));
if (modeComboBox.GetComboBoxValue() != mode.ToString())
{
modeComboBox.Click();
_mainWindow.FindElementByName(mode.ToString()).SendClick();
}
var locationComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowLocation");
timer.SplitLog(nameof(locationComboBox));
if (locationComboBox.GetComboBoxValue() != location.ToString())
{
locationComboBox.Click();
_mainWindow.FindElementByName(location.ToString()).SendClick();
}
var stateComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowState");
timer.SplitLog(nameof(stateComboBox));
if (stateComboBox.GetComboBoxValue() != state.ToString())
{
stateComboBox.Click();
_mainWindow.FindElementByAccessibilityId($"ShowWindowState{state}").SendClick();
}
var canResizeCheckBox = _mainWindow.FindElementByAccessibilityId("ShowWindowCanResize");
timer.SplitLog(nameof(canResizeCheckBox));
if (canResizeCheckBox.GetIsChecked() != canResize)
canResizeCheckBox.Click();
timer.Reset();
var showButton = _mainWindow.FindElementByAccessibilityId("ShowWindow");
timer.SplitLog(nameof(showButton));
var result = _session.GetNewWindow(()=> showButton.Click());
timer.SplitLog("GetNewWindow");
return result;
}
private static WindowInfo GetWindowInfo(IWindowElement window)
{
var dictionary = new Dictionary<string, string>();
PixelRect? ReadOwnerRect()
{
if (dictionary.ContainsKey("ownerrect"))
{
return PixelRect.Parse(dictionary["ownerrect"]);
}
return null;
}
var retry = 0;
for (;;)
{
try
{
var timer = new SplitTimer();
var summary = window.FindElementByAccessibilityId("CurrentSummary").Text;
var items = summary.Split("::");
foreach (var item in items)
{
var kv = item.Split(":");
if (kv.Length == 2)
{
var key = kv[0];
var value = kv[1];
dictionary[key] = value;
}
}
timer.SplitLog("summary");
var result = new WindowInfo(
Size.Parse(dictionary["clientSize"]),
Size.Parse(dictionary["frameSize"]),
PixelPoint.Parse(dictionary["position"]),
ReadOwnerRect(),
PixelRect.Parse(dictionary["screen"]),
double.Parse(dictionary["scaling"]),
Enum.Parse<WindowState>(dictionary["windowstate"]));
return result;
}
catch (OpenQA.Selenium.NoSuchElementException) when (retry++ < 3)
{
// MacOS sometimes seems to need a bit of time to get itself back in order after switching out
// of fullscreen.
Thread.Sleep(1000);
}
}
}
public enum ShowWindowMode
{
NonOwned,
Owned,
Modal
}
private record WindowInfo(
Size ClientSize,
Size FrameSize,
PixelPoint Position,
PixelRect? OwnerRect,
PixelRect ScreenRect,
double Scaling,
WindowState WindowState);
}
}

197
tests/Avalonia.IntegrationTests.Appium/WindowTestsBase.cs

@ -0,0 +1,197 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Avalonia.Controls;
using Avalonia.IntegrationTests.Appium.Wrappers;
using OpenQA.Selenium.Appium;
using Xunit;
using Xunit.Sdk;
namespace Avalonia.IntegrationTests.Appium;
public class WindowTestsBase
{
private readonly ISession _session;
private readonly IWindowElement _mainWindow;
public WindowTestsBase(ISession session)
{
_session = session;
_mainWindow = _session.GetWindow("MainWindow");
}
protected IWindowElement MainWindow => _mainWindow;
protected ISession Session => _session;
protected IWindowElement OpenWindow(
Size? size,
ShowWindowMode mode,
WindowStartupLocation location = WindowStartupLocation.Manual,
WindowState state = Controls.WindowState.Normal,
bool canResize = true)
{
var timer = new SplitTimer();
var elements = _mainWindow.GetChildren();
timer.SplitLog("getChildren");
if (size.HasValue)
{
var sizeTextBox = _mainWindow.FindElementByAccessibilityId("ShowWindowSize");
timer.SplitLog(nameof(sizeTextBox));
sizeTextBox.SendKeys($"{size.Value.Width}, {size.Value.Height}");
}
var modeComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowMode");
timer.SplitLog(nameof(modeComboBox));
if (modeComboBox.GetComboBoxValue() != mode.ToString())
{
modeComboBox.Click();
_mainWindow.FindElementByName(mode.ToString()).SendClick();
}
var locationComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowLocation");
timer.SplitLog(nameof(locationComboBox));
if (locationComboBox.GetComboBoxValue() != location.ToString())
{
locationComboBox.Click();
_mainWindow.FindElementByName(location.ToString()).SendClick();
}
var stateComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowState");
timer.SplitLog(nameof(stateComboBox));
if (stateComboBox.GetComboBoxValue() != state.ToString())
{
stateComboBox.Click();
_mainWindow.FindElementByAccessibilityId($"ShowWindowState{state}").SendClick();
}
var canResizeCheckBox = _mainWindow.FindElementByAccessibilityId("ShowWindowCanResize");
timer.SplitLog(nameof(canResizeCheckBox));
if (canResizeCheckBox.GetIsChecked() != canResize)
canResizeCheckBox.Click();
timer.Reset();
var showButton = _mainWindow.FindElementByAccessibilityId("ShowWindow");
timer.SplitLog(nameof(showButton));
var result = _session.GetNewWindow(() => showButton.Click());
timer.SplitLog("GetNewWindow");
return result;
}
protected 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);
}
}
protected static WindowInfo GetWindowInfo(IWindowElement window)
{
var dictionary = new Dictionary<string, string>();
PixelRect? ReadOwnerRect()
{
if (dictionary.ContainsKey("ownerrect"))
{
return PixelRect.Parse(dictionary["ownerrect"]);
}
return null;
}
var retry = 0;
for (;;)
{
try
{
var timer = new SplitTimer();
var summary = window.FindElementByAccessibilityId("CurrentSummary").Text;
var items = summary.Split("::");
foreach (var item in items)
{
var kv = item.Split(":");
if (kv.Length == 2)
{
var key = kv[0];
var value = kv[1];
dictionary[key] = value;
}
}
timer.SplitLog("summary");
var result = new WindowInfo(
Size.Parse(dictionary["clientSize"]),
Size.Parse(dictionary["frameSize"]),
PixelPoint.Parse(dictionary["position"]),
ReadOwnerRect(),
PixelRect.Parse(dictionary["screen"]),
double.Parse(dictionary["scaling"]),
Enum.Parse<WindowState>(dictionary["windowstate"]));
return result;
}
catch (OpenQA.Selenium.NoSuchElementException) when (retry++ < 3)
{
// MacOS sometimes seems to need a bit of time to get itself back in order after switching out
// of fullscreen.
Thread.Sleep(1000);
}
}
}
protected int GetWindowOrder(IWindowElement window)
{
var order = window.FindByXPath("//*[@identifier='CurrentOrder']");
return int.Parse(order.Text);
}
public enum ShowWindowMode
{
NonOwned,
Owned,
Modal
}
protected record WindowInfo(
Size ClientSize,
Size FrameSize,
PixelPoint Position,
PixelRect? OwnerRect,
PixelRect ScreenRect,
double Scaling,
WindowState WindowState);
}

94
tests/Avalonia.IntegrationTests.Appium/WindowTests_MacOS.cs

@ -13,13 +13,13 @@ using Xunit;
namespace Avalonia.IntegrationTests.Appium
{
[Collection("Default")]
public class WindowTests_MacOS
public class WindowTests_MacOS : WindowTestsBase
{
private readonly IWindowElement _mainWindow;
private readonly ISession _session;
private readonly AppiumDriver<AppiumWebElement> _driver;
public WindowTests_MacOS(DefaultAppFixture fixture)
public WindowTests_MacOS(DefaultAppFixture fixture) : base (fixture.Session)
{
_session = fixture.Session;
_driver = fixture.Driver;
@ -48,7 +48,7 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_Modal_Dialog_Stays_InFront_Of_Parent()
{
using (var window = OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(200, 100), ShowWindowMode.Modal, WindowStartupLocation.Manual))
{
_mainWindow.Click();
@ -61,9 +61,17 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_Modal_Dialog_Stays_InFront_Of_Parent_When_Clicking_Resize_Grip()
{
AppiumWebElement GetWindow(string identifier)
{
// The Avalonia a11y tree currently exposes two nested Window elements, this is a bug and should be fixed
// but in the meantime use the `parent::' selector to return the parent "real" window.
return _driver.FindElementByXPath(
$"XCUIElementTypeWindow//*[@identifier='{identifier}']/parent::XCUIElementTypeWindow");
}
var mainWindow = GetWindow("MainWindow");
using (var window = OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(200, 100), ShowWindowMode.Modal, WindowStartupLocation.Manual))
{
new Actions(_driver)
.MoveToElement(mainWindow, 100, 1)
@ -92,7 +100,7 @@ namespace Avalonia.IntegrationTests.Appium
try
{
using (var window = OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(200, 100), ShowWindowMode.Modal, WindowStartupLocation.Manual))
{
var secondaryWindowIndex = GetWindowOrder(window);
Assert.Equal(1, secondaryWindowIndex);
@ -107,7 +115,7 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_Owned_Dialog_Stays_InFront_Of_Parent()
{
using (var window = OpenWindow(new PixelSize(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
{
_mainWindow.SendClick();
var secondaryWindowIndex = GetWindowOrder(window);
@ -129,7 +137,7 @@ namespace Avalonia.IntegrationTests.Appium
Assert.Equal("FullScreen", windowState.Text);
// Open child window.
using (var window = OpenWindow(new PixelSize(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
{
_mainWindow.SendClick();
var secondaryWindowIndex = GetWindowOrder(window);
@ -150,7 +158,7 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_Owned_Dialog_Stays_InFront_Of_Parent_After_Modal_Closed()
{
using (var window = OpenWindow(new PixelSize(200, 300), ShowWindowMode.Owned, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(200, 300), ShowWindowMode.Owned, WindowStartupLocation.Manual))
{
OpenWindow(null, ShowWindowMode.Modal, WindowStartupLocation.Manual).Dispose();
@ -166,7 +174,7 @@ namespace Avalonia.IntegrationTests.Appium
IElement windowState;
// Open child window.
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
using (OpenWindow(new Size(200, 100), ShowWindowMode.Owned, WindowStartupLocation.Manual))
{
// Enter fullscreen
_mainWindow.FindElementByAccessibilityId("EnterFullscreen").Click();
@ -199,7 +207,7 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_NonOwned_Window_Does_Not_Stay_InFront_Of_Parent()
{
using (var window = OpenWindow(new PixelSize(800, 100), ShowWindowMode.NonOwned, WindowStartupLocation.Manual))
using (var window = OpenWindow(new Size(800, 100), ShowWindowMode.NonOwned, WindowStartupLocation.Manual))
{
_mainWindow.Click();
@ -215,10 +223,10 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void WindowOrder_Owned_Is_Correct_After_Closing_Window()
{
using (var window = OpenWindow(new PixelSize(300, 500), ShowWindowMode.Owned, WindowStartupLocation.CenterOwner))
using (var window = OpenWindow(new Size(300, 500), ShowWindowMode.Owned, WindowStartupLocation.CenterOwner))
{
// Open a second child window, and close it.
using (OpenWindow(new PixelSize(200, 200), ShowWindowMode.Owned, WindowStartupLocation.CenterOwner))
using (OpenWindow(new Size(200, 200), ShowWindowMode.Owned, WindowStartupLocation.CenterOwner))
{
}
@ -237,7 +245,7 @@ namespace Avalonia.IntegrationTests.Appium
Assert.True(zoomButton.Enabled);
Assert.True(miniaturizeButton.Enabled);
using (OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner))
using (OpenWindow(new Size(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner))
{
Assert.False(closeButton.Enabled);
Assert.False(zoomButton.Enabled);
@ -248,7 +256,7 @@ namespace Avalonia.IntegrationTests.Appium
[PlatformFact(TestPlatforms.MacOS)]
public void Minimize_Button_Is_Disabled_On_Modal_Dialog()
{
using (var secondaryWindow = OpenWindow(new PixelSize(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner))
using (var secondaryWindow = OpenWindow(new Size(200, 100), ShowWindowMode.Modal, WindowStartupLocation.CenterOwner))
{
var (closeButton, miniaturizeButton, zoomButton) = (secondaryWindow as WindowElement).GetChromeButtons();
@ -262,7 +270,7 @@ namespace Avalonia.IntegrationTests.Appium
[InlineData(ShowWindowMode.Owned)]
public void Minimize_Button_Disabled_Owned_Window(ShowWindowMode mode)
{
using (var secondaryWindow = OpenWindow(new PixelSize(200, 100), mode, WindowStartupLocation.Manual))
using (var secondaryWindow = OpenWindow(new Size(200, 100), mode, WindowStartupLocation.Manual))
{
var (_, miniaturizeButton, _) = (secondaryWindow as WindowElement).GetChromeButtons();
@ -275,7 +283,7 @@ namespace Avalonia.IntegrationTests.Appium
[InlineData(ShowWindowMode.NonOwned)]
public void Minimize_Button_Minimizes_Window(ShowWindowMode mode)
{
using (var secondaryWindow = OpenWindow(new PixelSize(200, 100), mode, WindowStartupLocation.Manual))
using (var secondaryWindow = OpenWindow(new Size(200, 100), mode, WindowStartupLocation.Manual))
{
var (_, miniaturizeButton, _) = (secondaryWindow as WindowElement).GetChromeButtons();
@ -332,59 +340,5 @@ namespace Avalonia.IntegrationTests.Appium
Assert.False(zoomButton.Enabled);
}
}
private IWindowElement OpenWindow(
PixelSize? size,
ShowWindowMode mode,
WindowStartupLocation location,
bool canResize = true)
{
var sizeTextBox = _mainWindow.FindElementByAccessibilityId("ShowWindowSize");
var modeComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowMode");
var locationComboBox = _mainWindow.FindElementByAccessibilityId("ShowWindowLocation");
var canResizeCheckBox = _mainWindow.FindElementByAccessibilityId("ShowWindowCanResize");
var showButton = _mainWindow.FindElementByAccessibilityId("ShowWindow");
if (size.HasValue)
sizeTextBox.SendKeys($"{size.Value.Width}, {size.Value.Height}");
if (modeComboBox.GetComboBoxValue() != mode.ToString())
{
modeComboBox.Click();
_mainWindow.FindElementByName(mode.ToString()).SendClick();
}
if (locationComboBox.GetComboBoxValue() != location.ToString())
{
locationComboBox.Click();
_mainWindow.FindElementByName(location.ToString()).SendClick();
}
if (canResizeCheckBox.GetIsChecked() != canResize)
canResizeCheckBox.Click();
return _session.GetNewWindow(() => showButton.Click());
}
private AppiumWebElement GetWindow(string identifier)
{
// The Avalonia a11y tree currently exposes two nested Window elements, this is a bug and should be fixed
// but in the meantime use the `parent::' selector to return the parent "real" window.
return _driver.FindElementByXPath(
$"XCUIElementTypeWindow//*[@identifier='{identifier}']/parent::XCUIElementTypeWindow");
}
private int GetWindowOrder(IWindowElement window)
{
var order = window.FindByXPath("//*[@identifier='CurrentOrder']");
return int.Parse(order.Text);
}
public enum ShowWindowMode
{
NonOwned,
Owned,
Modal
}
}
}

30
tests/Avalonia.IntegrationTests.Appium/Wrappers/Element.cs

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
@ -16,34 +17,9 @@ public class Element : IElement
protected IWebElement Inner => _inner;
private string? _name;
public string Name
{
get
{
if (_name is null)
{
_name = _inner.GetAttribute("title");
}
return _name;
}
}
private string? _text;
public virtual string Name => _inner.GetAttribute("title");
public string Text
{
get
{
if (_text is null)
{
_text = _inner.Text;
}
return _text;
}
}
public virtual string Text => _inner.Text;
public bool Enabled => _inner.Enabled;

16
tests/Avalonia.IntegrationTests.Appium/Wrappers/MacSession.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Mac;
@ -23,7 +24,6 @@ public class MacSession : ISession
{
get
{
// Double XCUIElementTypeWindow is a hack for Avalonia a11y returning 2 nested windows.
return _driver.FindElementsByXPath(
"/XCUIElementTypeApplication/XCUIElementTypeWindow")
.Select(x => new WindowElement(x))
@ -48,14 +48,18 @@ public class MacSession : ISession
var timer = new SplitTimer();
// Store the old window.
var oldWindows = Windows.ToList();
var oldWindowTitles = Windows.ToList()
.Select(x => (Value: x.Text, x))
.Where(x => !string.IsNullOrEmpty(x.Value))
.ToDictionary(x => x.Value, x => x.x);
timer.SplitLog("list windows");
// open window with click
openWindow();
timer.SplitLog("openWindow");
Thread.Sleep(1000);
// find the new window
var newWindows = Windows.ToList();
@ -70,11 +74,11 @@ public class MacSession : ISession
.Where(x => !string.IsNullOrEmpty(x.Value))
.ToDictionary(x => x.Value, x => x.x);
var result = Assert.Single(newWindowTitles.Where(x => !oldWindows.Contains(x.Value))).Value;
var result = Assert.Single(newWindowTitles.Keys.Except(oldWindowTitles.Keys));
timer.SplitLog("Asset");
return result;
return newWindowTitles[result];
}
internal static Func<IWebElement, object> GetElementFactory()

35
tests/Avalonia.IntegrationTests.Appium/Wrappers/WindowElement.cs

@ -7,11 +7,46 @@ namespace Avalonia.IntegrationTests.Appium.Wrappers;
public class WindowElement : Element, IWindowElement, IEquatable<IWindowElement>
{
private bool _isDisposed;
private string? _text;
private string? _name;
public WindowElement(IWebElement inner) : base(inner)
{
}
public override string Name
{
get
{
if (_name is null)
{
_name = base.Name;
}
return _name;
}
}
public override string Text
{
get
{
if (_text is null)
{
try
{
_text = base.Text;
}
catch (Exception)
{
_text = "DeadBeef";
}
}
return _text;
}
}
public string Id => (Inner as AppiumWebElement).Id;
public void Close()

Loading…
Cancel
Save