Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/nuget/test/integration/Selenium.W…
Browse files Browse the repository at this point in the history
…ebDriver-4.27.0
  • Loading branch information
Dor-bl authored Dec 27, 2024
2 parents a696467 + e900ce2 commit 4a81efa
Showing 15 changed files with 110 additions and 92 deletions.
12 changes: 10 additions & 2 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -34,9 +34,17 @@ steps:
displayName: 'Install Appium'

- task: DotNetCoreCLI@2
displayName: 'Run unit tests - $(buildConfiguration)'
displayName: 'Run .NET48 unit tests - $(buildConfiguration)'
inputs:
command: 'test'
arguments: '--no-build --configuration $(buildConfiguration) --filter AppiumLocalServerLaunchingTest|DirectConnectTest'
arguments: '--no-build --configuration $(buildConfiguration) --filter AppiumLocalServerLaunchingTest|DirectConnectTest --framework net48'
publishTestResults: true
projects: '**/*.Tests.csproj'

- task: DotNetCoreCLI@2
displayName: 'Run .NET 6 unit tests - $(buildConfiguration)'
inputs:
command: 'test'
arguments: '--no-build --configuration $(buildConfiguration) --filter AppiumLocalServerLaunchingTest|DirectConnectTest --framework net6.0'
publishTestResults: true
projects: '**/*.Tests.csproj'
Original file line number Diff line number Diff line change
@@ -170,12 +170,6 @@ public static float GetDisplayDensity(IExecuteMethod executeMethod) => Convert.T

#endregion

public static bool IsLocked(IExecuteMethod executeMethod) =>
(bool) executeMethod.Execute(AppiumDriverCommand.IsLocked).Value;

public static void Unlock(IExecuteMethod executeMethod) =>
executeMethod.Execute(AppiumDriverCommand.UnlockDevice);

public static Dictionary<string, object> GetSettings(IExecuteMethod executeMethod) =>
(Dictionary<string, object>) executeMethod.Execute(AppiumDriverCommand.GetSettings).Value;

64 changes: 55 additions & 9 deletions src/Appium.Net/Appium/Android/AndroidDriver.cs
Original file line number Diff line number Diff line change
@@ -287,21 +287,67 @@ public IList<string> GetPerformanceDataTypes() =>

#region Device Interactions

/**
* This method locks a device.
*/
public void Lock() => AppiumCommandExecutionHelper.Lock(this, 0);
/// <summary>
/// Locks the device. Optionally, unlocks it after a specified number of seconds.
/// </summary>
/// <param name="seconds">
/// The number of seconds after which the device will be automatically unlocked.
/// Set to 0 or leave it empty to require manual unlock.
/// </param>
/// <exception cref="WebDriverException">Thrown if the command execution fails.</exception>
public void Lock(int? seconds = null)
{
var parameters = new Dictionary<string, object>();

if (seconds.HasValue && seconds.Value > 0)
{
parameters["seconds"] = seconds.Value;
}

ExecuteScript("mobile: lock", parameters);
}

/// <summary>
/// Check if the device is locked
/// </summary>
/// <returns>true if device is locked, false otherwise</returns>
public bool IsLocked() => AndroidCommandExecutionHelper.IsLocked(this);
public bool IsLocked() => (bool)ExecuteScript("mobile: isLocked");

/// <summary>
/// Unlocks the device if it is locked. No operation if the device's screen is not locked.
/// </summary>
/// <param name="key">The unlock key. See the documentation on appium:unlockKey capability for more details.</param>
/// <param name="type">The unlock type. See the documentation on appium:unlockType capability for more details.</param>
/// <param name="strategy">Optional unlock strategy. See the documentation on appium:unlockStrategy capability for more details.</param>
/// <param name="timeoutMs">Optional unlock timeout in milliseconds. See the documentation on appium:unlockSuccessTimeout capability for more details.</param>
/// <exception cref="ArgumentException">Thrown when required arguments are null or empty.</exception>
/// <exception cref="WebDriverException">Thrown if the command execution fails.</exception>
public void Unlock(string key, string type, string? strategy = null, int? timeoutMs = null)
{
if (string.IsNullOrWhiteSpace(key))
throw new ArgumentException("Unlock key is required and cannot be null or whitespace.", nameof(key));

if (string.IsNullOrWhiteSpace(type))
throw new ArgumentException("Unlock type is required and cannot be null or whitespace.", nameof(type));

var parameters = new Dictionary<string, object>
{
{ "key", key },
{ "type", type }
};

/**
* This method unlocks a device.
*/
public void Unlock() => AndroidCommandExecutionHelper.Unlock(this);
if (strategy != null && !string.IsNullOrWhiteSpace(strategy))
{
parameters["strategy"] = strategy;
}

if (timeoutMs.HasValue)
{
parameters["timeoutMs"] = timeoutMs.Value;
}

ExecuteScript("mobile: unlock", parameters);
}

#endregion

6 changes: 0 additions & 6 deletions src/Appium.Net/Appium/AppiumCommand.cs
Original file line number Diff line number Diff line change
@@ -78,12 +78,6 @@ public class AppiumCommand

new AppiumCommand(HttpCommandInfo.PostCommand, AppiumDriverCommand.ShakeDevice,
"/session/{sessionId}/appium/device/shake"),
new AppiumCommand(HttpCommandInfo.PostCommand, AppiumDriverCommand.LockDevice,
"/session/{sessionId}/appium/device/lock"),
new AppiumCommand(HttpCommandInfo.PostCommand, AppiumDriverCommand.IsLocked,
"/session/{sessionId}/appium/device/is_locked"),
new AppiumCommand(HttpCommandInfo.PostCommand, AppiumDriverCommand.UnlockDevice,
"/session/{sessionId}/appium/device/unlock"),
new AppiumCommand(HttpCommandInfo.PostCommand, AppiumDriverCommand.PressKeyCode,
"/session/{sessionId}/appium/device/press_keycode"),
new AppiumCommand(HttpCommandInfo.PostCommand, AppiumDriverCommand.LongPressKeyCode,
5 changes: 0 additions & 5 deletions src/Appium.Net/Appium/AppiumCommandExecutionHelper.cs
Original file line number Diff line number Diff line change
@@ -82,11 +82,6 @@ public static bool IsKeyboardShown(IExecuteMethod executeMethod)

#endregion

public static void Lock(IExecuteMethod executeMethod, int seconds) =>
executeMethod.Execute(AppiumDriverCommand.LockDevice,
new Dictionary<string, object>()
{["seconds"] = seconds});

public static void SetClipboard(IExecuteMethod executeMethod, ClipboardContentType clipboardContentType,
string base64Content)
{
15 changes: 0 additions & 15 deletions src/Appium.Net/Appium/AppiumDriverCommand.cs
Original file line number Diff line number Diff line change
@@ -23,21 +23,6 @@ public class AppiumDriverCommand
/// </summary>
public const string ShakeDevice = "shakeDevice";

/// <summary>
/// Represents the Lock Device Mapping command
/// </summary>
public const string LockDevice = "lockDevice";

/// <summary>
/// Represents the Unlock Device Mapping command
/// </summary>
public const string UnlockDevice = "unlockDevice";

/// <summary>
/// Represents the Is Device Locked Mapping command
/// </summary>
public const string IsLocked = "isLocked";

/// <summary>
/// Toggle's the Airplane Mode ("Flight Safe Mode") Command
/// </summary>
9 changes: 0 additions & 9 deletions src/Appium.Net/Appium/iOS/IOSCommandExecutionHelper.cs
Original file line number Diff line number Diff line change
@@ -33,15 +33,6 @@ public static void PerformTouchID(IExecuteMethod executeMethod, bool match) =>
executeMethod.Execute(AppiumDriverCommand.TouchID,
new Dictionary<string, object> {["match"] = match});

public static bool IsLocked(IExecuteMethod executeMethod) =>
(bool)executeMethod.Execute(AppiumDriverCommand.IsLocked).Value;

public static void Unlock(IExecuteMethod executeMethod) =>
executeMethod.Execute(AppiumDriverCommand.UnlockDevice);

public static void Lock(IExecuteMethod executeMethod) =>
executeMethod.Execute(AppiumDriverCommand.LockDevice);

public static void SetClipboardUrl(IExecuteMethod executeMethod, string url)
{
var urlEncoded = WebUtility.UrlEncode(url);
30 changes: 23 additions & 7 deletions src/Appium.Net/Appium/iOS/IOSDriver.cs
Original file line number Diff line number Diff line change
@@ -187,19 +187,35 @@ public Dictionary<string, object> Settings
public void HideKeyboard(string key, string strategy = null) =>
AppiumCommandExecutionHelper.HideKeyboard(this, strategy, key);

public void PerformTouchID(bool match) => IOSCommandExecutionHelper.PerformTouchID(this, match);

/// <summary>
/// Locks the device.
/// Check if the device is locked
/// </summary>
/// <param name="seconds">The number of seconds during which the device need to be locked for.</param>
public void Lock(int seconds) => AppiumCommandExecutionHelper.Lock(this, seconds);
/// <returns>true if device is locked, false otherwise</returns>
public bool IsLocked() => (bool)ExecuteScript("mobile: isLocked");

public void PerformTouchID(bool match) => IOSCommandExecutionHelper.PerformTouchID(this, match);
/// <summary>
/// Locks the device. Optionally, unlocks it after a specified number of seconds.
/// </summary>
/// <param name="seconds">
/// The number of seconds after which the device will be automatically unlocked.
/// Set to 0 or leave it empty to require manual unlock.
/// </param>
/// <exception cref="WebDriverException">Thrown if the command execution fails.</exception>
public void Lock(int? seconds = null)
{
var parameters = new Dictionary<string, object>();

public bool IsLocked() => IOSCommandExecutionHelper.IsLocked(this);
if (seconds.HasValue && seconds.Value > 0)
{
parameters["seconds"] = seconds.Value;
}

public void Unlock() => IOSCommandExecutionHelper.Unlock(this);
ExecuteScript("mobile: lock", parameters);
}

public void Lock() => IOSCommandExecutionHelper.Lock(this);
public void Unlock() => ExecuteScript("mobile: unlock");

/// <summary>
/// Sets the content to the clipboard
2 changes: 1 addition & 1 deletion test/integration/Android/LockDeviceTest.cs
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ public void LockTest()
{
_driver.Lock();
Assert.That(_driver.IsLocked(), Is.EqualTo(true));
_driver.Unlock();
_driver.Unlock("12345","password");
Assert.That(_driver.IsLocked(), Is.EqualTo(false));
}
}
2 changes: 1 addition & 1 deletion test/integration/Android/Session/LogTests.cs
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@ public void CanCaptureBugReportTest()
Assert.That(availableLogTypes, Has.Member(BugReportLogType));

var bugReportLogEntry = _driver.Manage().Logs.GetLog(BugReportLogType);
Assert.That(bugReportLogEntry, Is.Not.Null.And.Count.EqualTo(1));
Assert.That(bugReportLogEntry, Is.Not.Null.And.Count.AtLeast(1));
var bugReportLogPath = bugReportLogEntry.FirstOrDefault()?.Message;

var match = Regex.Match(bugReportLogPath ?? throw new InvalidOperationException(), @"^([\s\S])*.zip");
8 changes: 4 additions & 4 deletions test/integration/Appium.Net.Integration.Tests.csproj
Original file line number Diff line number Diff line change
@@ -9,14 +9,14 @@
<None Remove="apps\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit.Analyzers" Version="4.3.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.3.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.4.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="System.Text.Json" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Appium.Net\Appium.Net.csproj" />
2 changes: 1 addition & 1 deletion test/integration/IOS/AlertTests.cs
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ public void TextAlertTest()
_driver.FindElement(MobileBy.IosNSPredicate("label == 'show alert'")).Click();
Thread.Sleep(500);
string alertText = _driver.SwitchTo().Alert().Text;
Assert.That(alertText, Is.EqualTo("Cool title\r\nthis alert is so cool."));
Assert.That(alertText, Is.EqualTo("Cool title\nthis alert is so cool."));
}
}
}
6 changes: 3 additions & 3 deletions test/integration/IOS/ClipboardTest.cs
Original file line number Diff line number Diff line change
@@ -15,11 +15,11 @@ public class ClipboardTest
private const string ClipboardTestString = "Hello Clipboard";
private const string Base64RegexPattern = @"^[a-zA-Z0-9\+/]*={0,2}$";

[SetUp]
[OneTimeSetUp]
public void Setup()
{
var capabilities = Caps.GetIosCaps(Apps.Get("iosUICatalogApp"));
capabilities.AddAdditionalAppiumOption(MobileCapabilityType.FullReset, true);
capabilities.AddAdditionalAppiumOption(MobileCapabilityType.FullReset, false);
var serverUri = Env.ServerIsRemote() ? AppiumServers.RemoteServerUri : AppiumServers.LocalServiceUri;

_driver = new IOSDriver(serverUri, capabilities, Env.InitTimeoutSec);
@@ -94,7 +94,7 @@ public void WhenClipboardIsEmpty_GetClipboardTextShouldReturnEmptyString()
Assert.That(() => _driver.GetClipboardText(), Is.Empty);
}

[TearDown]
[OneTimeTearDown]
public void TearDown()
{
if (_driver.IsLocked())
22 changes: 11 additions & 11 deletions test/integration/IOS/ScrollingSearchingTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Appium.Net.Integration.Tests.helpers;
using System.Collections.Generic;
using Appium.Net.Integration.Tests.helpers;
using NUnit.Framework;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.iOS;
@@ -29,21 +30,20 @@ public void AfterEach()
}

[Test]
public void ScrollToTestCase()
public void ScrollToToolbarsElementUsingToVisibleTrueTest()
{
var slider = _driver
.FindElement(new ByIosUIAutomation(".tableViews()[0]"
+ ".scrollToElementWithPredicate(\"name CONTAINS 'Slider'\")"));
Assert.That(slider.GetAttribute("name"), Is.EqualTo("Sliders"));
var Toolbars = _driver.FindElement(new ByIosNSPredicate("name == 'Toolbars'"));
_driver.ExecuteScript("mobile: scroll", new Dictionary<string, string> { { "element", Toolbars.Id }, { "toVisible", "true" } });
Assert.That(Toolbars.Displayed, Is.True, "The 'Toolbars' element should be visible after scrolling.");
}

[Test]
public void ScrollToExactTestCase()
public void ScrollToSwitchesElementUsingDirectionDownTest()
{
var table = _driver.FindElement(new ByIosUIAutomation(".tableViews()[0]"));
var slider = table.FindElement(
new ByIosUIAutomation(".scrollToElementWithPredicate(\"name CONTAINS 'Slider'\")"));
Assert.That(slider.GetAttribute("name"), Is.EqualTo("Sliders"));
var table = _driver.FindElement(new ByIosNSPredicate("type == 'XCUIElementTypeTable'"));
_driver.ExecuteScript("mobile: scroll", new Dictionary<string, string> { { "direction", "down" }, { "element", table.Id } });
var switches = table.FindElement(new ByIosNSPredicate("name CONTAINS 'Switches'"));
Assert.That(switches.GetAttribute("visible"), Is.EqualTo("true"));
}
}
}
13 changes: 1 addition & 12 deletions test/integration/IOS/SearchingTest.cs
Original file line number Diff line number Diff line change
@@ -42,20 +42,9 @@ public void FindByAccessibilityIdTest()
By byAccessibilityId = new ByAccessibilityId("ComputeSumButton");
Assert.Multiple(() =>
{
Assert.That(Is.Not.EqualTo(_driver.FindElement(byAccessibilityId).Text), null);
Assert.That(string.IsNullOrEmpty(_driver.FindElement(byAccessibilityId).Text), Is.False);
Assert.That(_driver.FindElements(byAccessibilityId), Is.Not.Empty);
});
}

[Test]
public void FindByByIosUiAutomationTest()
{
By byIosUiAutomation = new ByIosUIAutomation(".elements().withName(\"Answer\")");
Assert.Multiple(() =>
{
Assert.That(_driver.FindElement(byIosUiAutomation).Text, Is.Not.Null);
Assert.That(_driver.FindElements(byIosUiAutomation), Is.Not.Empty);
});
}
}
}

0 comments on commit 4a81efa

Please sign in to comment.