Skip to content

Commit

Permalink
[Testing] Add scroll methods to UITest (#19181)
Browse files Browse the repository at this point in the history
* Added more scroll methods to UITests

* Using ScrollStrategy

* Fix merge issues

* Fix merge issue
  • Loading branch information
jsuarezruiz committed Dec 11, 2023
1 parent 5753b98 commit 089eacc
Show file tree
Hide file tree
Showing 4 changed files with 326 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/Controls/tests/UITests/Tests/ScrollViewUITests.cs
Expand Up @@ -74,5 +74,18 @@ public void ScrollToElement3End()
Assert.Ignore("This test is failing, likely due to product issue");
}
}

[Test]
[Description("Scroll down the ScrollView using a gesture")]
public void ScrollUpAndDownWithGestures()
{
this.IgnoreIfPlatforms(new TestDevice[] { TestDevice.Mac, TestDevice.Windows });

App.ScrollDown("thescroller", ScrollStrategy.Gesture, 0.75);
App.Screenshot("Element scrolled down");

App.ScrollUp("thescroller", ScrollStrategy.Gesture, 0.75);
App.Screenshot("Element scrolled up");
}
}
}
215 changes: 215 additions & 0 deletions src/TestUtils/src/UITest.Appium/Actions/AppiumScrollActions.cs
@@ -0,0 +1,215 @@
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.MultiTouch;
using UITest.Core;

namespace UITest.Appium
{
public enum ScrollStrategy
{
Auto,
Gesture,
Programmatically
}

public class AppiumScrollActions : ICommandExecutionGroup
{
const string ScrollLeftCommand = "scrollLeft";
const string ScrollDownCommand = "scrollDown";
const string ScrollRightCommand = "scrollRight";
const string ScrollUpCommand = "scrollUp";

readonly AppiumApp _appiumApp;

readonly List<string> _commands = new()
{
ScrollLeftCommand,
ScrollDownCommand,
ScrollRightCommand,
ScrollUpCommand,
};

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

public bool IsCommandSupported(string commandName)
{
return _commands.Contains(commandName, StringComparer.OrdinalIgnoreCase);
}

public CommandResponse Execute(string commandName, IDictionary<string, object> parameters)
{
return commandName switch
{
ScrollLeftCommand => ScrollLeft(parameters),
ScrollDownCommand => ScrollDown(parameters),
ScrollRightCommand => ScrollRight(parameters),
ScrollUpCommand => ScrollUp(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
}

CommandResponse ScrollLeft(IDictionary<string, object> parameters)
{
parameters.TryGetValue("element", out var value);
var element = GetAppiumElement(value);

if (element is null)
return CommandResponse.FailedEmptyResponse;

ScrollStrategy strategy = (ScrollStrategy)parameters["strategy"];
double swipePercentage = (double)parameters["swipePercentage"];
int swipeSpeed = (int)parameters["swipeSpeed"];
bool withInertia = (bool)parameters["withInertia"];

ScrollToLeft(_appiumApp.Driver, element, strategy, swipePercentage, swipeSpeed, withInertia);

return CommandResponse.SuccessEmptyResponse;
}

CommandResponse ScrollDown(IDictionary<string, object> parameters)
{
parameters.TryGetValue("element", out var value);
var element = GetAppiumElement(value);

if (element is null)
return CommandResponse.FailedEmptyResponse;

ScrollStrategy strategy = (ScrollStrategy)parameters["strategy"];
double swipePercentage = (double)parameters["swipePercentage"];
int swipeSpeed = (int)parameters["swipeSpeed"];
bool withInertia = (bool)parameters["withInertia"];

ScrollToDown(_appiumApp.Driver, element, strategy, swipePercentage, swipeSpeed, withInertia);

return CommandResponse.SuccessEmptyResponse;
}

CommandResponse ScrollRight(IDictionary<string, object> parameters)
{
parameters.TryGetValue("element", out var value);
var element = GetAppiumElement(value);

if (element is null)
return CommandResponse.FailedEmptyResponse;

ScrollStrategy strategy = (ScrollStrategy)parameters["strategy"];
double swipePercentage = (double)parameters["swipePercentage"];
int swipeSpeed = (int)parameters["swipeSpeed"];
bool withInertia = (bool)parameters["withInertia"];

ScrollToRight(_appiumApp.Driver, element, strategy, swipePercentage, swipeSpeed, withInertia);

return CommandResponse.SuccessEmptyResponse;
}

CommandResponse ScrollUp(IDictionary<string, object> parameters)
{
parameters.TryGetValue("element", out var value);
var element = GetAppiumElement(value);

if (element is null)
return CommandResponse.FailedEmptyResponse;

ScrollStrategy strategy = (ScrollStrategy)parameters["strategy"];
double swipePercentage = (double)parameters["swipePercentage"];
int swipeSpeed = (int)parameters["swipeSpeed"];
bool withInertia = (bool)parameters["withInertia"];

ScrollToUp(_appiumApp.Driver, element, strategy, swipePercentage, swipeSpeed, withInertia);

return CommandResponse.SuccessEmptyResponse;
}

static AppiumElement? GetAppiumElement(object? element)
{
if (element is AppiumElement appiumElement)
{
return appiumElement;
}
else if (element is AppiumDriverElement driverElement)
{
return driverElement.AppiumElement;
}

return null;
}

static void ScrollToLeft(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
var position = element.Location;
var size = element.Size;

int startX = (int)(position.X + (size.Width * 0.05));
int startY = position.Y + size.Height / 2;

int endX = (int)(position.X + (size.Width * swipePercentage));
int endY = startY;

new TouchAction(driver)
.Press(startX, startY)
.Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0)
.MoveTo(endX, endY)
.Release()
.Perform();
}

static void ScrollToDown(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
var position = element.Location;
var size = element.Size;

int startX = position.X + size.Width / 2;
int startY = (int)(position.Y + (size.Height * swipePercentage));

int endX = startX;
int endY = (int)(position.Y + (size.Height * 0.05));

new TouchAction(driver)
.Press(startX, startY)
.Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0)
.MoveTo(endX, endY)
.Release()
.Perform();
}

static void ScrollToRight(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
var position = element.Location;
var size = element.Size;

int startX = (int)(position.X + (size.Width * swipePercentage));
int startY = position.Y + size.Height / 2;

int endX = (int)(position.X + (size.Width * 0.05));
int endY = startY;

new TouchAction(driver)
.Press(startX, startY)
.Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0)
.MoveTo(endX, endY)
.Release()
.Perform();
}

static void ScrollToUp(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
var position = element.Location;
var size = element.Size;

int startX = position.X + size.Width / 2;
int startY = (int)(position.Y + (size.Height * 0.05));

int endX = startX;
int endY = (int)(position.Y + (size.Height * swipePercentage));

new TouchAction(driver)
.Press(startX, startY)
.Wait(strategy != ScrollStrategy.Programmatically ? swipeSpeed : 0)
.MoveTo(endX, endY)
.Release()
.Perform();
}
}
}
3 changes: 2 additions & 1 deletion src/TestUtils/src/UITest.Appium/AppiumApp.cs
@@ -1,4 +1,4 @@
using OpenQA.Selenium;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Enums;
using UITest.Core;
Expand All @@ -23,6 +23,7 @@ public AppiumApp(AppiumDriver driver, IConfig config)
_commandExecutor.AddCommandGroup(new AppiumVirtualKeyboardActions(this));
_commandExecutor.AddCommandGroup(new AppiumSliderActions(this));
_commandExecutor.AddCommandGroup(new AppiumSwipeActions(this));
_commandExecutor.AddCommandGroup(new AppiumScrollActions(this));
_commandExecutor.AddCommandGroup(new AppiumOrientationActions(this));
}

Expand Down
99 changes: 96 additions & 3 deletions src/TestUtils/src/UITest.Appium/HelperExtensions.cs
@@ -1,4 +1,4 @@
using System.Collections.Immutable;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
Expand Down Expand Up @@ -224,7 +224,7 @@ public static void SwipeLeftToRight(this IApp app, string marked, double swipePe

app.CommandExecutor.Execute("swipeLeftToRight", new Dictionary<string, object>
{
{ "element", elementToSwipe},
{ "element", elementToSwipe},
{ "swipePercentage", swipePercentage },
{ "swipeSpeed", swipeSpeed },
{ "withInertia", withInertia }
Expand Down Expand Up @@ -270,6 +270,99 @@ public static void SwipeRightToLeft(this IApp app, string marked, double swipePe
});
}

/// <summary>
/// Scrolls left on the first element matching query.
/// </summary>
/// <param name="app">Represents the main gateway to interact with an app.</param>
/// <param name="marked">Marked selector to match.</param>
/// <param name="strategy">Strategy for scrolling element.</param>
/// <param name="swipePercentage">How far across the element to swipe (from 0.0 to 1.0).</param>
/// <param name="swipeSpeed">The speed of the gesture.</param>
/// <param name="withInertia">Whether swipes should cause inertia.</param>
public static void ScrollLeft(this IApp app, string marked, ScrollStrategy strategy = ScrollStrategy.Auto, double swipePercentage = 0.67, int swipeSpeed = 500, bool withInertia = true)
{
var elementToSwipe = app.FindElement(marked);

app.CommandExecutor.Execute("scrollLeft", new Dictionary<string, object>
{
{ "element", elementToSwipe},
{ "strategy", strategy },
{ "swipePercentage", swipePercentage },
{ "swipeSpeed", swipeSpeed },
{ "withInertia", withInertia }
});
}

/// <summary>
/// Scrolls down on the first element matching query.
/// </summary>
/// <param name="app">Represents the main gateway to interact with an app.</param>
/// <param name="marked">Marked selector to match.</param>
/// <param name="strategy">Strategy for scrolling element.</param>
/// <param name="swipePercentage">How far across the element to swipe (from 0.0 to 1.0).</param>
/// <param name="swipeSpeed">The speed of the gesture.</param>
/// <param name="withInertia">Whether swipes should cause inertia.</param>
public static void ScrollDown(this IApp app, string marked, ScrollStrategy strategy = ScrollStrategy.Auto, double swipePercentage = 0.67, int swipeSpeed = 500, bool withInertia = true)
{
var elementToSwipe = app.FindElement(marked);

app.CommandExecutor.Execute("scrollDown", new Dictionary<string, object>
{
{ "element", elementToSwipe},
{ "strategy", strategy },
{ "swipePercentage", swipePercentage },
{ "swipeSpeed", swipeSpeed },
{ "withInertia", withInertia }
});
}

/// <summary>
/// Scrolls right on the first element matching query.
/// </summary>
/// <param name="app">Represents the main gateway to interact with an app.</param>
/// <param name="marked">Marked selector to match.</param>
/// <param name="strategy">Strategy for scrolling element.</param>
/// <param name="swipePercentage">How far across the element to swipe (from 0.0 to 1.0).</param>
/// <param name="swipeSpeed">The speed of the gesture.</param>
/// <param name="withInertia">Whether swipes should cause inertia.</param>
public static void ScrollRight(this IApp app, string marked, ScrollStrategy strategy = ScrollStrategy.Auto, double swipePercentage = 0.67, int swipeSpeed = 500, bool withInertia = true)
{
var elementToSwipe = app.FindElement(marked);

app.CommandExecutor.Execute("scrollRight", new Dictionary<string, object>
{
{ "element", elementToSwipe},
{ "strategy", strategy },
{ "swipePercentage", swipePercentage },
{ "swipeSpeed", swipeSpeed },
{ "withInertia", withInertia }
});
}

/// <summary>
/// Scrolls up on the first element matching query.
/// </summary>
/// <param name="app">Represents the main gateway to interact with an app.</param>
/// <param name="marked">Marked selector to match.</param>
/// <param name="strategy">Strategy for scrolling element.</param>
/// <param name="swipePercentage">How far across the element to swipe (from 0.0 to 1.0).</param>
/// <param name="swipeSpeed">The speed of the gesture.</param>
/// <param name="withInertia">Whether swipes should cause inertia.</param>
public static void ScrollUp(this IApp app, string marked, ScrollStrategy strategy = ScrollStrategy.Auto, double swipePercentage = 0.67, int swipeSpeed = 500, bool withInertia = true)
{
var elementToSwipe = app.FindElement(marked);

app.CommandExecutor.Execute("scrollUp", new Dictionary<string, object>
{
{ "element", elementToSwipe},
{ "strategy", strategy },
{ "swipePercentage", swipePercentage },
{ "swipeSpeed", swipeSpeed },
{ "withInertia", withInertia }
});
}

/// <summary>
/// Changes the device orientation to landscape mode.
/// </summary>
/// <param name="app">Represents the main gateway to interact with an app.</param>
Expand Down Expand Up @@ -392,4 +485,4 @@ public static void SetSliderValue(this IApp app, string marked, double value, do
Wait(query, i => i == null, timeoutMessage, timeout, retryFrequency);
}
}
}
}

0 comments on commit 089eacc

Please sign in to comment.