Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
129 changes: 126 additions & 3 deletions src/TestUtils/src/UITest.Appium/Actions/AppiumScrollActions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using OpenQA.Selenium.Appium;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Interactions;
using OpenQA.Selenium.Appium.Mac;
using OpenQA.Selenium.Appium.MultiTouch;
using OpenQA.Selenium.Interactions;
using UITest.Core;

Expand All @@ -16,22 +15,28 @@ public enum ScrollStrategy

public class AppiumScrollActions : ICommandExecutionGroup
{
static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(15);

const int ScrollTouchDownTime = 100;
const int ProgrammaticallyScrollTime = 0;

const string ScrollLeftCommand = "scrollLeft";
const string ScrollDownCommand = "scrollDown";
const string ScrollDownToCommand = "scrollDownTo";
const string ScrollRightCommand = "scrollRight";
const string ScrollUpCommand = "scrollUp";
const string ScrollUpToCommand = "scrollUpTo";

readonly AppiumApp _appiumApp;

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

public AppiumScrollActions(AppiumApp appiumApp)
Expand All @@ -50,8 +55,10 @@ public CommandResponse Execute(string commandName, IDictionary<string, object> p
{
ScrollLeftCommand => ScrollLeft(parameters),
ScrollDownCommand => ScrollDown(parameters),
ScrollDownToCommand => ScrollDownTo(parameters),
ScrollRightCommand => ScrollRight(parameters),
ScrollUpCommand => ScrollUp(parameters),
ScrollUpToCommand => ScrollUpTo(parameters),
_ => CommandResponse.FailedEmptyResponse,
};
}
Expand Down Expand Up @@ -92,6 +99,25 @@ CommandResponse ScrollDown(IDictionary<string, object> parameters)
return CommandResponse.SuccessEmptyResponse;
}

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

if (element is null)
return CommandResponse.FailedEmptyResponse;

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

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

return CommandResponse.SuccessEmptyResponse;
}

CommandResponse ScrollRight(IDictionary<string, object> parameters)
{
parameters.TryGetValue("element", out var value);
Expand Down Expand Up @@ -128,6 +154,25 @@ CommandResponse ScrollUp(IDictionary<string, object> parameters)
return CommandResponse.SuccessEmptyResponse;
}

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

if (element is null)
return CommandResponse.FailedEmptyResponse;

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

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

return CommandResponse.SuccessEmptyResponse;
}

static AppiumElement? GetAppiumElement(object? element)
{
if (element is AppiumElement appiumElement)
Expand Down Expand Up @@ -168,6 +213,45 @@ void ScrollToDown(AppiumDriver driver, AppiumElement element, ScrollStrategy str

PerformActions(driver, startX, startY, endX, endY, strategy, swipeSpeed, element?.Id);
}

AppiumElement? ScrollToDownTo(AppiumDriver driver, string marked, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
var timeout = DefaultTimeout;
var retryFrequency = TimeSpan.FromMilliseconds(500);

DateTime start = DateTime.Now;

AppiumElement? result = ScrollDownUntilPresent(driver, marked, element, strategy, swipePercentage, swipeSpeed, withInertia);

while (result is not null)
{
long elapsed = DateTime.Now.Subtract(start).Ticks;
if (elapsed >= timeout.Ticks)
{
throw new TimeoutException("Timed out on scroll to.");
}

Task.Delay(retryFrequency.Milliseconds).Wait();
result = ScrollDownUntilPresent(driver, marked, element, strategy, swipePercentage, swipeSpeed, withInertia);
}

return result;
}

AppiumElement? ScrollDownUntilPresent(AppiumDriver driver, string marked, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
ScrollToDown(driver, element, strategy, swipePercentage, swipeSpeed, withInertia);

var result = driver.FindElement(By.Id(marked));

if (result is null)
{
// Android (text), iOS (label), Windows (Name)
result = driver.FindElement(By.XPath("//*[@text='" + marked + "' or @label='" + marked + "' or @Name='" + marked + "']"));
}

return result;
}

void ScrollToRight(AppiumDriver driver, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
Expand All @@ -194,6 +278,45 @@ void ScrollToUp(AppiumDriver driver, AppiumElement element, ScrollStrategy strat
PerformActions(driver, startX, startY, endX, endY, strategy, swipeSpeed, element?.Id);
}

AppiumElement? ScrollToUpTo(AppiumDriver driver, string target, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
var timeout = DefaultTimeout;
var retryFrequency = TimeSpan.FromMilliseconds(500);

DateTime start = DateTime.Now;

AppiumElement? result = ScrollUpUntilPresent(driver, target, element, strategy, swipePercentage, swipeSpeed, withInertia);

while (result is not null)
{
long elapsed = DateTime.Now.Subtract(start).Ticks;
if (elapsed >= timeout.Ticks)
{
throw new TimeoutException("Timed out on scroll to.");
}

Task.Delay(retryFrequency.Milliseconds).Wait();
result = ScrollUpUntilPresent(driver, target, element, strategy, swipePercentage, swipeSpeed, withInertia);
}

return result;
}

AppiumElement? ScrollUpUntilPresent(AppiumDriver driver, string marked, AppiumElement element, ScrollStrategy strategy, double swipePercentage, int swipeSpeed, bool withInertia = true)
{
ScrollToUp(driver, element, strategy, swipePercentage, swipeSpeed, withInertia);

var result = driver.FindElement(By.Id(marked));

if (result is null)
{
// Android (text), iOS (label), Windows (Name)
result = driver.FindElement(By.XPath("//*[@text='" + marked + "' or @label='" + marked + "' or @Name='" + marked + "']"));
}

return result;
}

virtual protected void PerformActions(
AppiumDriver driver,
int startX,
Expand Down
Loading
Loading