-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add accessibility ID to the TrayPopupRoot on Windows * [Windows] Add left click and menu item click e2e tests for TrayIcon * [Windows] Add TrayIcon visibility toggle tests * Implement macOS tray icon tests * Make it easier to read tray icon logs * Try to handle win10 accessibility names * Try to upload PageSource * Set condition: always * Hopefully, it works on CI * Try to upload PageSource #2 * Fix win10, hopefully for the last time
- Loading branch information
Showing
8 changed files
with
215 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 152 additions & 0 deletions
152
tests/Avalonia.IntegrationTests.Appium/TrayIconTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Threading; | ||
using OpenQA.Selenium; | ||
using OpenQA.Selenium.Appium; | ||
using OpenQA.Selenium.Interactions; | ||
using Xunit; | ||
|
||
namespace Avalonia.IntegrationTests.Appium; | ||
|
||
[Collection("Default")] | ||
public class TrayIconTests : IDisposable | ||
{ | ||
private readonly AppiumDriver _session; | ||
private readonly AppiumDriver? _rootSession; | ||
private const string TrayIconName = "IntegrationTestApp TrayIcon"; | ||
|
||
public TrayIconTests(DefaultAppFixture fixture) | ||
{ | ||
_session = fixture.Session; | ||
|
||
// "Root" is a special name for windows the desktop session, that has access to task bar. | ||
if (OperatingSystem.IsWindows()) | ||
{ | ||
_rootSession = fixture.CreateNestedSession("Root"); | ||
} | ||
|
||
var tabs = _session.FindElementByAccessibilityId("MainTabs"); | ||
var tab = tabs.FindElementByName("Desktop"); | ||
tab.Click(); | ||
} | ||
|
||
// Left click is only supported on Windows. | ||
[PlatformFact(TestPlatforms.Windows)] | ||
public void Should_Handle_Left_Click() | ||
{ | ||
var avaloinaTrayIconButton = GetTrayIconButton(_rootSession ?? _session, TrayIconName); | ||
Assert.NotNull(avaloinaTrayIconButton); | ||
|
||
avaloinaTrayIconButton.SendClick(); | ||
|
||
Thread.Sleep(2000); | ||
|
||
var checkBox = _session.FindElementByAccessibilityId("TrayIconClicked"); | ||
Assert.True(checkBox.GetIsChecked()); | ||
} | ||
|
||
[Fact] | ||
public void Should_Handle_Context_Menu_Item_Click() | ||
{ | ||
var avaloinaTrayIconButton = GetTrayIconButton(_rootSession ?? _session, TrayIconName); | ||
Assert.NotNull(avaloinaTrayIconButton); | ||
|
||
var contextMenu = ShowAndGetTrayMenu(avaloinaTrayIconButton, TrayIconName); | ||
Assert.NotNull(contextMenu); | ||
|
||
var menuItem = contextMenu.FindElementByName("Raise Menu Clicked"); | ||
menuItem.SendClick(); | ||
|
||
Thread.Sleep(2000); | ||
|
||
var checkBox = _session.FindElementByAccessibilityId("TrayIconMenuClicked"); | ||
Assert.True(checkBox.GetIsChecked()); | ||
} | ||
|
||
[Fact] | ||
public void Can_Toggle_TrayIcon_Visibility() | ||
{ | ||
var avaloinaTrayIconButton = GetTrayIconButton(_rootSession ?? _session, TrayIconName); | ||
Assert.NotNull(avaloinaTrayIconButton); | ||
|
||
var toggleButton = _session.FindElementByAccessibilityId("ToggleTrayIconVisible"); | ||
toggleButton.SendClick(); | ||
|
||
avaloinaTrayIconButton = GetTrayIconButton(_rootSession ?? _session, TrayIconName); | ||
Assert.Null(avaloinaTrayIconButton); | ||
|
||
toggleButton.SendClick(); | ||
|
||
avaloinaTrayIconButton = GetTrayIconButton(_rootSession ?? _session, TrayIconName); | ||
Assert.NotNull(avaloinaTrayIconButton); | ||
} | ||
|
||
private static AppiumWebElement? GetTrayIconButton(AppiumDriver session, string trayIconName) | ||
{ | ||
if (OperatingSystem.IsWindows()) | ||
{ | ||
var taskBar = session.FindElementsByClassName("Shell_TrayWnd") | ||
.FirstOrDefault() ?? throw new InvalidOperationException("Couldn't find Taskbar on current system."); | ||
|
||
if (TryToGetIcon(taskBar, trayIconName) is { } trayIcon) | ||
{ | ||
return trayIcon; | ||
} | ||
else | ||
{ | ||
// Add a sleep here, as previous test might still run popup closing animation. | ||
Thread.Sleep(1000); | ||
|
||
// win11: SystemTrayIcon | ||
// win10: Notification Chevron | ||
var trayIconsButton = taskBar.FindElementsByAccessibilityId("SystemTrayIcon").FirstOrDefault() | ||
?? taskBar.FindElementsByName("Notification Chevron").FirstOrDefault() | ||
?? throw new InvalidOperationException("SystemTrayIcon cannot be found."); | ||
trayIconsButton.Click(); | ||
|
||
// win11: TopLevelWindowForOverflowXamlIsland | ||
// win10: NotifyIconOverflowWindow | ||
var trayIconsFlyout = session.FindElementsByClassName("TopLevelWindowForOverflowXamlIsland").FirstOrDefault() | ||
?? session.FindElementsByClassName("NotifyIconOverflowWindow").FirstOrDefault() | ||
?? throw new InvalidOperationException("System tray overflow window cannot be found."); | ||
return TryToGetIcon(trayIconsFlyout, trayIconName); | ||
} | ||
|
||
static AppiumWebElement? TryToGetIcon(AppiumWebElement parent, string trayIconName) => | ||
parent.FindElementsByName(trayIconName).LastOrDefault() | ||
// Some icons (including Avalonia) for some reason include leading whitespace in their name. | ||
// Couldn't find any info on that, which is weird. | ||
?? parent.FindElementsByName(" " + trayIconName).LastOrDefault(); | ||
} | ||
if (OperatingSystem.IsMacOS()) | ||
{ | ||
return session.FindElementsByXPath("//XCUIElementTypeStatusItem").FirstOrDefault(); | ||
} | ||
|
||
throw new PlatformNotSupportedException(); | ||
} | ||
|
||
private static AppiumWebElement ShowAndGetTrayMenu(AppiumWebElement trayIcon, string trayIconName) | ||
{ | ||
if (OperatingSystem.IsWindows()) | ||
{ | ||
var session = (AppiumDriver)trayIcon.WrappedDriver; | ||
new Actions(trayIcon.WrappedDriver).ContextClick(trayIcon).Perform(); | ||
|
||
Thread.Sleep(1000); | ||
|
||
return session.FindElementByXPath($"//Window[@AutomationId='AvaloniaTrayPopupRoot_{trayIconName}']"); | ||
} | ||
else | ||
{ | ||
trayIcon.Click(); | ||
return trayIcon.FindElementByXPath("//XCUIElementTypeStatusItem/XCUIElementTypeMenu"); | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_rootSession?.Dispose(); | ||
} | ||
} |