New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Testing] Add scroll methods to UITest #19181
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
215 changes: 215 additions & 0 deletions
215
src/TestUtils/src/UITest.Appium/Actions/AppiumScrollActions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using System.Collections.Immutable; | ||
using System.Collections.Immutable; | ||
using System.Collections.ObjectModel; | ||
using System.Diagnostics; | ||
using System.Drawing; | ||
|
@@ -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 } | ||
|
@@ -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> | ||
jfversluis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// <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) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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> | ||
|
@@ -392,4 +485,4 @@ public static void SetSliderValue(this IApp app, string marked, double value, do | |
Wait(query, i => i == null, timeoutMessage, timeout, retryFrequency); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added test to validate the added methods (scroll with gestures)