Skip to content

Commit

Permalink
Fix the tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mattleibow committed Jun 7, 2024
1 parent 026da41 commit 17ea9c6
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 147 deletions.
147 changes: 72 additions & 75 deletions src/TestUtils/src/UITest.Appium/Actions/AppiumAndroidAlertActions.cs
Original file line number Diff line number Diff line change
@@ -1,95 +1,92 @@
using System.Collections.ObjectModel;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium;
using UITest.Core;

namespace UITest.Appium
namespace UITest.Appium;

public class AppiumAndroidAlertActions : ICommandExecutionGroup
{
public class AppiumAndroidAlertActions : ICommandExecutionGroup
const string GetAlertsCommand = "getAlerts";
const string GetAlertButtonsCommand = "getAlertButtons";
const string GetAlertTextCommand = "getAlertText";

readonly List<string> _commands = new()
{
GetAlertsCommand,
GetAlertButtonsCommand,
GetAlertTextCommand,
};
readonly AppiumApp _appiumApp;

public AppiumAndroidAlertActions(AppiumApp appiumApp)
{
_appiumApp = appiumApp;
}

public bool IsCommandSupported(string commandName)
{
const string GetAlertsCommand = "getAlerts";
const string GetAlertButtonsCommand = "getAlertButtons";
const string GetAlertTextCommand = "getAlertText";
return _commands.Contains(commandName, StringComparer.OrdinalIgnoreCase);
}

readonly List<string> _commands = new()
public CommandResponse Execute(string commandName, IDictionary<string, object> parameters)
{
return commandName switch
{
GetAlertsCommand,
GetAlertButtonsCommand,
GetAlertTextCommand,
GetAlertsCommand => GetAlerts(parameters),
GetAlertButtonsCommand => GetAlertButtons(parameters),
GetAlertTextCommand => GetAlertText(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
readonly AppiumApp _appiumApp;
}

public AppiumAndroidAlertActions(AppiumApp appiumApp)
{
_appiumApp = appiumApp;
}
CommandResponse GetAlerts(IDictionary<string, object> parameters)
{
var alerts = _appiumApp.Query.ById("parentPanel");

public bool IsCommandSupported(string commandName)
{
return _commands.Contains(commandName, StringComparer.OrdinalIgnoreCase);
}
if (alerts is null || alerts.Count == 0)
return CommandResponse.FailedEmptyResponse;

public CommandResponse Execute(string commandName, IDictionary<string, object> parameters)
{
return commandName switch
{
GetAlertsCommand => GetAlerts(parameters),
GetAlertButtonsCommand => GetAlertButtons(parameters),
GetAlertTextCommand => GetAlertText(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
}

CommandResponse GetAlerts(IDictionary<string, object> parameters)
{
var alerts = _appiumApp.Query.ById("parentPanel");
return new CommandResponse(alerts, CommandResponseResult.Success);
}

if (alerts is null || alerts.Count == 0)
return CommandResponse.FailedEmptyResponse;
CommandResponse GetAlertButtons(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;

return new CommandResponse(alerts, CommandResponseResult.Success);
}
var items = AppiumQuery.ByClass("android.widget.ListView")
.FindElements(alert, _appiumApp)
.FirstOrDefault()
?.ByClass("android.widget.TextView");

CommandResponse GetAlertButtons(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;
var buttons = AppiumQuery.ByClass("android.widget.Button")
.FindElements(alert, _appiumApp);

var items = AppiumQuery.ByClass("android.widget.ListView")
.FindElements(alert, _appiumApp)
.FirstOrDefault()
?.ByClass("android.widget.TextView");
var all = new List<IUIElement>();
if (items is not null)
all.AddRange(items);
all.AddRange(buttons);

var buttons = AppiumQuery.ByClass("android.widget.Button")
.FindElements(alert, _appiumApp);
return new CommandResponse(all, CommandResponseResult.Success);
}

var all = new List<IUIElement>();
if (items is not null)
all.AddRange(items);
all.AddRange(buttons);
CommandResponse GetAlertText(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;

return new CommandResponse(all, CommandResponseResult.Success);
}
var text = AppiumQuery.ByClass("android.widget.TextView").FindElements(alert, _appiumApp);
var strings = text.Select(t => t.GetText()).ToList();

CommandResponse GetAlertText(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;

var text = AppiumQuery.ByClass("android.widget.TextView").FindElements(alert, _appiumApp);
var strings = text.Select(t => t.GetText()).ToList();

return new CommandResponse(strings, CommandResponseResult.Success);
}

static AppiumElement? GetAppiumElement(object element) =>
element switch
{
AppiumElement appiumElement => appiumElement,
AppiumDriverElement driverElement => driverElement.AppiumElement,
_ => null
};
return new CommandResponse(strings, CommandResponseResult.Success);
}

static AppiumElement? GetAppiumElement(object element) =>
element switch
{
AppiumElement appiumElement => appiumElement,
AppiumDriverElement driverElement => driverElement.AppiumElement,
_ => null
};
}
133 changes: 64 additions & 69 deletions src/TestUtils/src/UITest.Appium/Actions/AppiumAppleAlertActions.cs
Original file line number Diff line number Diff line change
@@ -1,88 +1,83 @@
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium;
using UITest.Core;

namespace UITest.Appium
namespace UITest.Appium;

public abstract class AppiumAppleAlertActions : ICommandExecutionGroup
{
public class AppiumAppleAlertActions : ICommandExecutionGroup
const string GetAlertsCommand = "getAlerts";
const string GetAlertButtonsCommand = "getAlertButtons";
const string GetAlertTextCommand = "getAlertText";

readonly List<string> _commands = new()
{
GetAlertsCommand,
GetAlertButtonsCommand,
GetAlertTextCommand,
};
readonly AppiumApp _appiumApp;

public AppiumAppleAlertActions(AppiumApp appiumApp)
{
_appiumApp = appiumApp;
}

public bool IsCommandSupported(string commandName)
{
const string GetAlertsCommand = "getAlerts";
const string GetAlertButtonsCommand = "getAlertButtons";
const string GetAlertTextCommand = "getAlertText";
return _commands.Contains(commandName, StringComparer.OrdinalIgnoreCase);
}

readonly List<string> _commands = new()
public CommandResponse Execute(string commandName, IDictionary<string, object> parameters)
{
return commandName switch
{
GetAlertsCommand,
GetAlertButtonsCommand,
GetAlertTextCommand,
GetAlertsCommand => GetAlerts(parameters),
GetAlertButtonsCommand => GetAlertButtons(parameters),
GetAlertTextCommand => GetAlertText(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
readonly AppiumApp _appiumApp;
}

public AppiumAppleAlertActions(AppiumApp appiumApp)
{
_appiumApp = appiumApp;
}
protected abstract IReadOnlyCollection<IUIElement> OnGetAlerts(AppiumApp appiumApp, IDictionary<string, object> parameters);

public bool IsCommandSupported(string commandName)
{
return _commands.Contains(commandName, StringComparer.OrdinalIgnoreCase);
}
CommandResponse GetAlerts(IDictionary<string, object> parameters)
{
var alerts = OnGetAlerts(_appiumApp, parameters);

if (alerts is null || alerts.Count == 0)
return CommandResponse.FailedEmptyResponse;

public CommandResponse Execute(string commandName, IDictionary<string, object> parameters)
{
return commandName switch
{
GetAlertsCommand => GetAlerts(parameters),
GetAlertButtonsCommand => GetAlertButtons(parameters),
GetAlertTextCommand => GetAlertText(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
}

CommandResponse GetAlerts(IDictionary<string, object> parameters)
{
// first try the type used on iOS
var alerts = _appiumApp.FindElements(AppiumQuery.ByClass("XCUIElementTypeAlert"));
return new CommandResponse(alerts, CommandResponseResult.Success);
}

// then try the type used on macOS
if (alerts is null || alerts.Count == 0)
alerts = _appiumApp.FindElements(AppiumQuery.ByClass("XCUIElementTypeSheet"));
CommandResponse GetAlertButtons(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;

if (alerts is null || alerts.Count == 0)
return CommandResponse.FailedEmptyResponse;
var buttons = AppiumQuery.ByClass("XCUIElementTypeButton").FindElements(alert, _appiumApp);

return new CommandResponse(alerts, CommandResponseResult.Success);
}
return new CommandResponse(buttons, CommandResponseResult.Success);
}

CommandResponse GetAlertButtons(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;
CommandResponse GetAlertText(IDictionary<string, object> parameters)
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;

var buttons = AppiumQuery.ByClass("XCUIElementTypeButton").FindElements(alert, _appiumApp);
var text = AppiumQuery.ByClass("XCUIElementTypeStaticText").FindElements(alert, _appiumApp);
var strings = text.Select(t => t.GetText()).ToList();

return new CommandResponse(buttons, CommandResponseResult.Success);
}
return new CommandResponse(strings, CommandResponseResult.Success);
}

CommandResponse GetAlertText(IDictionary<string, object> parameters)
static AppiumElement? GetAppiumElement(object element) =>
element switch
{
var alert = GetAppiumElement(parameters["element"]);
if (alert is null)
return CommandResponse.FailedEmptyResponse;

var text = AppiumQuery.ByClass("XCUIElementTypeStaticText").FindElements(alert, _appiumApp);
var strings = text.Select(t => t.GetText()).ToList();

return new CommandResponse(strings, CommandResponseResult.Success);
}

static AppiumElement? GetAppiumElement(object element) =>
element switch
{
AppiumElement appiumElement => appiumElement,
AppiumDriverElement driverElement => driverElement.AppiumElement,
_ => null
};
}
AppiumElement appiumElement => appiumElement,
AppiumDriverElement driverElement => driverElement.AppiumElement,
_ => null
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using UITest.Core;

namespace UITest.Appium;

public class AppiumCatalystAlertActions : AppiumAppleAlertActions
{
public AppiumCatalystAlertActions(AppiumApp appiumApp)
: base(appiumApp)
{
}

protected override IReadOnlyCollection<IUIElement> OnGetAlerts(AppiumApp appiumApp, IDictionary<string, object> parameters)
{
// Catalyst always uses action sheets.
var alerts = appiumApp.FindElements(AppiumQuery.ByClass("XCUIElementTypeSheet"));

return alerts;
}
}
29 changes: 29 additions & 0 deletions src/TestUtils/src/UITest.Appium/Actions/AppiumIOSAlertActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using UITest.Core;

namespace UITest.Appium;

public class AppiumIOSAlertActions : AppiumAppleAlertActions
{
// Selects VISIBLE "Other" elements that are the direct child of
// a VISIBLE window AND are OVERLAYED on top of the first window.
const string PossibleAlertXPath =
"//XCUIElementTypeWindow[@visible='true']/XCUIElementTypeOther[@visible='true' and @index > 0]";

public AppiumIOSAlertActions(AppiumApp appiumApp)
: base(appiumApp)
{
}

protected override IReadOnlyCollection<IUIElement> OnGetAlerts(AppiumApp appiumApp, IDictionary<string, object> parameters)
{
// First try the type used on iOS.
var alerts = appiumApp.FindElements(AppiumQuery.ByClass("XCUIElementTypeAlert"));

// It appears iOS sometimes uses the XCUIElementTypeOther class for action sheets
// so we need a way to do a more fuzzy check.
if (alerts is null || alerts.Count == 0)
alerts = appiumApp.FindElements(AppiumQuery.ByXPath(PossibleAlertXPath));

return alerts;
}
}
2 changes: 1 addition & 1 deletion src/TestUtils/src/UITest.Appium/AppiumCatalystApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public AppiumCatalystApp(Uri remoteAddress, IConfig config)
{
_commandExecutor.AddCommandGroup(new AppiumCatalystMouseActions(this));
_commandExecutor.AddCommandGroup(new AppiumCatalystTouchActions(this));
_commandExecutor.AddCommandGroup(new AppiumAppleAlertActions(this));
_commandExecutor.AddCommandGroup(new AppiumCatalystAlertActions(this));
}

public override ApplicationState AppState
Expand Down
2 changes: 1 addition & 1 deletion src/TestUtils/src/UITest.Appium/AppiumIOSApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public AppiumIOSApp(Uri remoteAddress, IConfig config)
_commandExecutor.AddCommandGroup(new AppiumIOSMouseActions(this));
_commandExecutor.AddCommandGroup(new AppiumIOSTouchActions(this));
_commandExecutor.AddCommandGroup(new AppiumIOSVirtualKeyboardActions(this));
_commandExecutor.AddCommandGroup(new AppiumAppleAlertActions(this));
_commandExecutor.AddCommandGroup(new AppiumIOSAlertActions(this));
}

public override ApplicationState AppState
Expand Down
Loading

0 comments on commit 17ea9c6

Please sign in to comment.