Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 129 additions & 1 deletion src/Appium.Net/Appium/iOS/IOSDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
using System;
using System.Drawing;
using OpenQA.Selenium.Appium.iOS.Interfaces;
using OpenQA.Selenium.Appium.WebSocket;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace OpenQA.Selenium.Appium.iOS
{
public class IOSDriver : AppiumDriver, IHidesKeyboardWithKeyName, IHasClipboard,
IShakesDevice, IPerformsTouchID, IHasSettings
IShakesDevice, IPerformsTouchID, IHasSettings, IListensToSyslogMessages
{
private static readonly string Platform = MobilePlatform.IOS;
private readonly StringWebSocketClient _syslogClient = new();
private const int DefaultAppiumPort = 4723;

/// <summary>
/// Initializes a new instance of the IOSDriver class
Expand Down Expand Up @@ -328,5 +332,129 @@ public AppState GetAppState(string bundleId) =>
]
).ToString()
);

#region Syslog Broadcast

/// <summary>
/// Start syslog messages broadcast via web socket.
/// This method assumes that Appium server is running on localhost and
/// is assigned to the default port (4723).
/// </summary>
/// <remarks>
/// This implementation uses a custom WebSocket endpoint and is temporary.
/// In the future, this functionality will be replaced with WebDriver BiDi log events
/// when BiDi support for iOS device logs becomes available.
/// </remarks>
public async Task StartSyslogBroadcast() => await StartSyslogBroadcast("127.0.0.1", DefaultAppiumPort);

/// <summary>
/// Start syslog messages broadcast via web socket.
/// This method assumes that Appium server is assigned to the default port (4723).
/// </summary>
/// <param name="host">The name of the host where Appium server is running.</param>
/// <remarks>
/// This implementation uses a custom WebSocket endpoint and is temporary.
/// In the future, this functionality will be replaced with WebDriver BiDi log events
/// when BiDi support for iOS device logs becomes available.
/// </remarks>
public async Task StartSyslogBroadcast(string host) => await StartSyslogBroadcast(host, DefaultAppiumPort);

/// <summary>
/// Start syslog messages broadcast via web socket.
/// </summary>
/// <param name="host">The name of the host where Appium server is running.</param>
/// <param name="port">The port of the host where Appium server is running.</param>
/// <remarks>
/// This implementation uses a custom WebSocket endpoint and is temporary.
/// In the future, this functionality will be replaced with WebDriver BiDi log events
/// when BiDi support for iOS device logs becomes available.
/// </remarks>
public async Task StartSyslogBroadcast(string host, int port)
{
ExecuteScript("mobile: startLogsBroadcast", new Dictionary<string, object>());
var endpointUri = new Uri($"ws://{host}:{port}/ws/session/{SessionId}/appium/device/syslog");
Comment thread
Dor-bl marked this conversation as resolved.
Outdated
try
{
await _syslogClient.ConnectAsync(endpointUri);
}
catch
{
// The server-side broadcast was already started above; stop it so a failed
// WebSocket connection does not leave an orphaned broadcast on the Appium server.
try
{
ExecuteScript("mobile: stopLogsBroadcast", new Dictionary<string, object>());
}
catch
{
// Best-effort cleanup; surface the original connection failure below.
}
throw;
}
}

/// <summary>
/// Adds a new log messages broadcasting handler.
/// Several handlers might be assigned to a single server.
/// Multiple calls to this method will cause such handler
/// to be called multiple times.
/// </summary>
/// <param name="handler">A function, which accepts a single argument, which is the actual log message.</param>
public void AddSyslogMessagesListener(Action<string> handler) =>
_syslogClient.AddMessageHandler(handler);

/// <summary>
/// Adds a new log broadcasting errors handler.
/// Several handlers might be assigned to a single server.
/// Multiple calls to this method will cause such handler
/// to be called multiple times.
/// </summary>
/// <param name="handler">A function, which accepts a single argument, which is the actual exception instance.</param>
public void AddSyslogErrorsListener(Action<Exception> handler) =>
_syslogClient.AddErrorHandler(handler);

/// <summary>
/// Adds a new log broadcasting connection handler.
/// Several handlers might be assigned to a single server.
/// Multiple calls to this method will cause such handler
/// to be called multiple times.
/// </summary>
/// <param name="handler">A function, which is executed as soon as the client is successfully connected to the web socket.</param>
public void AddSyslogConnectionListener(Action handler) =>
_syslogClient.AddConnectionHandler(handler);

/// <summary>
/// Adds a new log broadcasting disconnection handler.
/// Several handlers might be assigned to a single server.
/// Multiple calls to this method will cause such handler
/// to be called multiple times.
/// </summary>
/// <param name="handler">A function, which is executed as soon as the client is successfully disconnected from the web socket.</param>
public void AddSyslogDisconnectionListener(Action handler) =>
_syslogClient.AddDisconnectionHandler(handler);

/// <summary>
/// Removes all existing syslog handlers.
/// </summary>
public void RemoveAllSyslogListeners() => _syslogClient.RemoveAllHandlers();

/// <summary>
/// Stops syslog messages broadcast via web socket.
/// </summary>
public async Task StopSyslogBroadcast()
{
try
{
ExecuteScript("mobile: stopLogsBroadcast", new Dictionary<string, object>());
}
finally
{
// Always disconnect the client so a failure stopping the server-side
// broadcast does not leave the WebSocket receive loop running.
await _syslogClient.DisconnectAsync();
}
Comment thread
Dor-bl marked this conversation as resolved.
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//limitations under the License.

using System;
using System.Threading.Tasks;

namespace OpenQA.Selenium.Appium.iOS.Interfaces
{
Expand All @@ -26,21 +27,21 @@ public interface IListensToSyslogMessages
/// This method assumes that Appium server is running on localhost and
/// is assigned to the default port (4723).
/// </summary>
void StartSyslogBroadcast();
Task StartSyslogBroadcast();
Comment thread
Dor-bl marked this conversation as resolved.

/// <summary>
/// Start syslog messages broadcast via web socket.
/// This method assumes that Appium server is assigned to the default port (4723).
/// </summary>
/// <param name="host">The name of the host where Appium server is running.</param>
void StartSyslogBroadcast(string host);
Task StartSyslogBroadcast(string host);

/// <summary>
/// Start syslog messages broadcast via web socket.
/// </summary>
/// <param name="host">The name of the host where Appium server is running.</param>
/// <param name="port">The port of the host where Appium server is running.</param>
void StartSyslogBroadcast(string host, int port);
Task StartSyslogBroadcast(string host, int port);

/// <summary>
/// Adds a new log messages broadcasting handler.
Expand Down Expand Up @@ -86,6 +87,6 @@ public interface IListensToSyslogMessages
/// <summary>
/// Stops syslog messages broadcast via web socket.
/// </summary>
void StopSyslogBroadcast();
Task StopSyslogBroadcast();
}
}
Loading
Loading