diff --git a/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.csproj b/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.csproj
index 2f1ede83..327e305e 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.csproj
+++ b/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.csproj
@@ -87,7 +87,7 @@
-
+
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.xml b/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.xml
index 2bc6bd24..ad496b61 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.xml
+++ b/Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.xml
@@ -231,6 +231,21 @@
Horizontal coordinate.
Vertical coordinate.
+
+
+ Scrolls window by coordinates using JavaScript.
+
+ Horizontal coordinate.
+ Vertical coordinate.
+
+
+
+ Scrolls portion of screen from specified origin
+
+ Origination point (either viewport or element, with possible offset).
+ Horizontal coordinate.
+ Vertical coordinate.
+
Executes JS script from embedded resource file (*.js).
@@ -335,11 +350,23 @@
Navigates back.
+
+
+ Move back a single entry in the browser's history as an asynchronous task.
+
+ A task object representing the asynchronous operation.
+
Navigates forward.
+
+
+ Move a single "item" forward in the browser's history as an asynchronous task.
+
+ A task object representing the asynchronous operation.
+
Navigates to desired url.
@@ -352,11 +379,31 @@
Uri representation of URL.
+
+
+ Navigate to a url as an asynchronous task.
+
+ String representation of where you want the browser to go.
+ A task object representing the asynchronous operation.
+
+
+
+ Navigate to a url as an asynchronous task.
+
+ Uri object of where you want the browser to go.
+ A task object representing the asynchronous operation.
+
Refreshes current page.
+
+
+ Reload the current page as an asynchronous task.
+
+ A task object representing the asynchronous operation.
+
Registers authentication handler and awaits to start network monitoring.
@@ -596,17 +643,17 @@
Logging preferences.
An object representing the result of the command, if applicable.
-
+
Sends the specified command and returns the associated command response.
The name of the command to send.
- The parameters of the command as a JToken object.
+ The parameters of the command as a JsonNode object.
A CancellationToken object to allow for cancellation of the command.
The execution timeout of the command in milliseconds.
to throw an exception if a response is not received; otherwise, .
Logging preferences.
- A JToken based on a command created with the specified command name and parameters.
+ A JsonNode based on a command created with the specified command name and parameters.
@@ -617,7 +664,7 @@
The execution timeout of the command in milliseconds.
to throw an exception if a response is not received; otherwise, .
Logging preferences.
- A JToken based on a command created with the specified command name and parameters.
+ A JsonNode based on a command created with the specified command name and parameters.
@@ -625,14 +672,14 @@
For more information, see .
-
+
Disable collecting and reporting metrics.
Current instance of .
A task for asynchronous command.
-
+
Enable collecting and reporting metrics.
@@ -1450,7 +1497,17 @@
- Perfroms right click on element.
+ Performs right click on element.
+
+
+
+
+ Scrolling page to the element.
+
+
+
+
+ Scrolling page from an element.
@@ -2311,6 +2368,11 @@
String representation of element's value
+
+
+ Clear element text.
+
+
Type text in an element.
@@ -2425,6 +2487,13 @@
horizontal coordinate
vertical coordinate
+
+
+ Scroll form via JavaScript without scrolling entire page
+
+ horizontal coordinate
+ vertical coordinate
+
DevTools Command/Result logging options.
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/Browser.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/Browser.cs
index 3f5d46cd..5b1c2f91 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/Browser.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/Browser.cs
@@ -10,6 +10,8 @@
using System.Collections.ObjectModel;
using IDevTools = OpenQA.Selenium.DevTools.IDevTools;
+using OpenQA.Selenium.Interactions;
+using static OpenQA.Selenium.Interactions.WheelInputDevice;
namespace Aquality.Selenium.Browsers
{
@@ -322,9 +324,32 @@ public ReadOnlyCollection GetLogs(string logKind)
/// Vertical coordinate.
public void ScrollWindowBy(int x, int y)
{
+ Logger.Info("loc.scrolling.by", x, y);
+ new Actions(Driver).ScrollByAmount(x, y).Perform();
+ }
+
+ ///
+ /// Scrolls window by coordinates using JavaScript.
+ ///
+ /// Horizontal coordinate.
+ /// Vertical coordinate.
+ public void ScrollWindowByViaJs(int x, int y)
+ {
+ Logger.Info("loc.scrolling.by.js", x, y);
ExecuteScript(JavaScript.ScrollWindowBy, x, y);
}
+ ///
+ /// Scrolls portion of screen from specified origin
+ ///
+ /// Origination point (either viewport or element, with possible offset).
+ /// Horizontal coordinate.
+ /// Vertical coordinate.
+ public void ScrollFromOrigin(ScrollOrigin scrollOrigin, int x, int y)
+ {
+ new Actions(Driver).ScrollFromOrigin(scrollOrigin, x, y).Perform();
+ }
+
///
/// Executes JS script from embedded resource file (*.js).
///
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserNavigation.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserNavigation.cs
index 98326a57..e1215acb 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserNavigation.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserNavigation.cs
@@ -1,6 +1,7 @@
using Aquality.Selenium.Core.Localization;
using OpenQA.Selenium;
using System;
+using System.Threading.Tasks;
namespace Aquality.Selenium.Browsers
{
@@ -28,6 +29,16 @@ public void Back()
driver.Navigate().Back();
}
+ ///
+ /// Move back a single entry in the browser's history as an asynchronous task.
+ ///
+ /// A task object representing the asynchronous operation.
+ public Task BackAsync()
+ {
+ Logger.Info("loc.browser.back");
+ return driver.Navigate().BackAsync();
+ }
+
///
/// Navigates forward.
///
@@ -37,6 +48,16 @@ public void Forward()
driver.Navigate().Forward();
}
+ ///
+ /// Move a single "item" forward in the browser's history as an asynchronous task.
+ ///
+ /// A task object representing the asynchronous operation.
+ public Task ForwardAsync()
+ {
+ Logger.Info("loc.browser.forward");
+ return driver.Navigate().ForwardAsync();
+ }
+
///
/// Navigates to desired url.
///
@@ -77,6 +98,28 @@ public void GoToUrl(Uri url)
}
}
+ ///
+ /// Navigate to a url as an asynchronous task.
+ ///
+ /// String representation of where you want the browser to go.
+ /// A task object representing the asynchronous operation.
+ public Task GoToUrlAsync(string url)
+ {
+ InfoLocNavigate(url);
+ return driver.Navigate().GoToUrlAsync(url);
+ }
+
+ ///
+ /// Navigate to a url as an asynchronous task.
+ ///
+ /// Uri object of where you want the browser to go.
+ /// A task object representing the asynchronous operation.
+ public Task GoToUrlAsync(Uri url)
+ {
+ InfoLocNavigate(url.ToString());
+ return driver.Navigate().GoToUrlAsync(url);
+ }
+
///
/// Refreshes current page.
///
@@ -86,6 +129,16 @@ public void Refresh()
driver.Navigate().Refresh();
}
+ ///
+ /// Reload the current page as an asynchronous task.
+ ///
+ /// A task object representing the asynchronous operation.
+ public Task RefreshAsync()
+ {
+ Logger.Info("loc.browser.refresh");
+ return driver.Navigate().RefreshAsync();
+ }
+
private void InfoLocNavigate(string url)
{
Logger.Info("loc.browser.navigate", url);
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserWindowNavigation.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserWindowNavigation.cs
index d68470b4..ec7f40e0 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserWindowNavigation.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/BrowserWindowNavigation.cs
@@ -2,7 +2,6 @@
using OpenQA.Selenium;
using System;
using System.Collections.Generic;
-using System.Linq;
namespace Aquality.Selenium.Browsers
{
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsHandling.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsHandling.cs
index f8e29580..1ef5948f 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsHandling.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsHandling.cs
@@ -1,6 +1,5 @@
using Aquality.Selenium.Core.Localization;
using Aquality.Selenium.Logging;
-using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.DevTools;
@@ -8,6 +7,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
@@ -31,7 +32,7 @@ public DevToolsHandling(IDevTools devToolsProvider)
wasDevToolsSessionClosed = false;
}
- private ILocalizedLogger Logger => AqualityServices.LocalizedLogger;
+ private static ILocalizedLogger Logger => AqualityServices.LocalizedLogger;
///
/// Gets a value indicating whether a DevTools session is active.
@@ -114,9 +115,9 @@ public object ExecuteCdpCommand(string commandName, Dictionary c
{
if (devToolsProvider is ChromiumDriver driver)
{
- LogCommand(commandName, JToken.FromObject(commandParameters), loggingOptions);
+ LogCommand(commandName, JsonSerializer.SerializeToNode(commandParameters), loggingOptions);
var result = driver.ExecuteCdpCommand(commandName, commandParameters);
- var formattedResult = JToken.FromObject(result);
+ var formattedResult = JsonSerializer.SerializeToNode(result);
LogCommandResult(formattedResult, loggingOptions);
return result;
}
@@ -130,17 +131,17 @@ public object ExecuteCdpCommand(string commandName, Dictionary c
/// Sends the specified command and returns the associated command response.
///
/// The name of the command to send.
- /// The parameters of the command as a JToken object.
+ /// The parameters of the command as a JsonNode object.
/// A CancellationToken object to allow for cancellation of the command.
/// The execution timeout of the command in milliseconds.
/// to throw an exception if a response is not received; otherwise, .
/// Logging preferences.
- /// A JToken based on a command created with the specified command name and parameters.
- public async Task SendCommand(string commandName, JToken commandParameters = null,
+ /// A JsonNode based on a command created with the specified command name and parameters.
+ public async Task SendCommand(string commandName, JsonNode commandParameters = null,
CancellationToken cancellationToken = default, int? millisecondsTimeout = null, bool throwExceptionIfResponseNotReceived = true,
DevToolsCommandLoggingOptions loggingOptions = null)
{
- var parameters = commandParameters ?? new JObject();
+ var parameters = commandParameters ?? new JsonObject();
LogCommand(commandName, parameters, loggingOptions);
var result = await devToolsProvider.GetDevToolsSession()
.SendCommand(commandName, parameters, cancellationToken, millisecondsTimeout, throwExceptionIfResponseNotReceived);
@@ -156,23 +157,23 @@ public async Task SendCommand(string commandName, JToken commandParamete
/// The execution timeout of the command in milliseconds.
/// to throw an exception if a response is not received; otherwise, .
/// Logging preferences.
- /// A JToken based on a command created with the specified command name and parameters.
- public async Task SendCommand(ICommand commandWithParameters,
+ /// A JsonNode based on a command created with the specified command name and parameters.
+ public async Task SendCommand(ICommand commandWithParameters,
CancellationToken cancellationToken = default, int? millisecondsTimeout = null, bool throwExceptionIfResponseNotReceived = true,
DevToolsCommandLoggingOptions loggingOptions = null)
{
- return await SendCommand(commandWithParameters.CommandName, JToken.FromObject(commandWithParameters),
+ return await SendCommand(commandWithParameters.CommandName, JsonSerializer.SerializeToNode(commandWithParameters, commandWithParameters.GetType()),
cancellationToken, millisecondsTimeout, throwExceptionIfResponseNotReceived, loggingOptions);
}
- private void LogCommand(string commandName, JToken commandParameters, DevToolsCommandLoggingOptions loggingOptions = null)
+ protected virtual void LogCommand(string commandName, JsonNode commandParameters, DevToolsCommandLoggingOptions loggingOptions = null)
{
var logging = (loggingOptions ?? new DevToolsCommandLoggingOptions()).Command;
if (!logging.Enabled)
{
return;
}
- if (commandParameters.Any())
+ if (IsNotEmpty(commandParameters))
{
Logger.LogByLevel(logging.LogLevel, "loc.browser.devtools.command.execute.withparams", commandName, commandParameters.ToString());
}
@@ -182,13 +183,18 @@ private void LogCommand(string commandName, JToken commandParameters, DevToolsCo
}
}
- private void LogCommandResult(JToken result, DevToolsCommandLoggingOptions loggingOptions = null)
+ protected virtual void LogCommandResult(JsonNode result, DevToolsCommandLoggingOptions loggingOptions = null)
{
var logging = (loggingOptions ?? new DevToolsCommandLoggingOptions()).Result;
- if (result.Any() && logging.Enabled)
+ if (IsNotEmpty(result) && logging.Enabled)
{
Logger.LogByLevel(logging.LogLevel, "loc.browser.devtools.command.execute.result", result.ToString());
}
}
+
+ private static bool IsNotEmpty(JsonNode jsonNode)
+ {
+ return jsonNode is JsonArray array ? array.Any() : (jsonNode as JsonObject).Any();
+ }
}
}
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsPerformanceExtensions.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsPerformanceExtensions.cs
index d926a2bf..8a806ff4 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsPerformanceExtensions.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/DevToolsPerformanceExtensions.cs
@@ -1,8 +1,8 @@
-using Newtonsoft.Json.Linq;
-using OpenQA.Selenium.DevTools.V85.Performance;
+using OpenQA.Selenium.DevTools.V85.Performance;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text.Json.Nodes;
using System.Threading.Tasks;
namespace Aquality.Selenium.Browsers
@@ -18,7 +18,7 @@ public static class DevToolsPerformanceExtensions
///
/// Current instance of .
/// A task for asynchronous command.
- public static async Task DisablePerfomanceMonitoring(this DevToolsHandling devTools)
+ public static async Task DisablePerformanceMonitoring(this DevToolsHandling devTools)
{
await devTools.SendCommand(new DisableCommandSettings());
}
@@ -30,7 +30,7 @@ public static async Task DisablePerfomanceMonitoring(this DevToolsHandling devTo
/// Time domain to use for collecting and reporting duration metrics.
/// Allowed Values: timeTicks, threadTicks.
/// A task for asynchronous command.
- public static async Task EnablePerfomanceMonitoring(this DevToolsHandling devTools, string timeDomain = null)
+ public static async Task EnablePerformanceMonitoring(this DevToolsHandling devTools, string timeDomain = null)
{
await devTools.SendCommand(new EnableCommandSettings { TimeDomain = timeDomain });
}
@@ -42,8 +42,8 @@ public static async Task EnablePerfomanceMonitoring(this DevToolsHandling devToo
/// A task for asynchronous command with current values for run-time metrics as result.
public static async Task> GetPerformanceMetrics(this DevToolsHandling devTools)
{
- JToken result = await devTools.SendCommand(new GetMetricsCommandSettings());
- return (result["metrics"] as JArray)
+ JsonNode result = await devTools.SendCommand(new GetMetricsCommandSettings());
+ return (result["metrics"].AsArray())
.ToDictionary(item => item["name"].ToString(), item => double.Parse(item["value"].ToString(), CultureInfo.InvariantCulture));
}
}
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/JavaScriptHandling.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/JavaScriptHandling.cs
index 8e1512d4..b362bb7a 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/JavaScriptHandling.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/JavaScriptHandling.cs
@@ -23,7 +23,7 @@ public JavaScriptHandling(IWebDriver driver)
javaScriptEngine = new JavaScriptEngine(driver);
}
- private ILocalizedLogger Logger => AqualityServices.LocalizedLogger;
+ private static ILocalizedLogger Logger => AqualityServices.LocalizedLogger;
///
/// Gets the read-only list of initialization scripts added for this JavaScript engine.
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Browsers/NetworkHandling.cs b/Aquality.Selenium/src/Aquality.Selenium/Browsers/NetworkHandling.cs
index 98840f37..cbe726d7 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Browsers/NetworkHandling.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Browsers/NetworkHandling.cs
@@ -21,7 +21,7 @@ public NetworkHandling(IWebDriver driver)
network = driver.Manage().Network;
}
- private ILocalizedLogger Logger => AqualityServices.LocalizedLogger;
+ private static ILocalizedLogger Logger => AqualityServices.LocalizedLogger;
///
/// A network request sent event.
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Configurations/WebDriverSettings/DriverSettings.cs b/Aquality.Selenium/src/Aquality.Selenium/Configurations/WebDriverSettings/DriverSettings.cs
index 420f9484..67743ba4 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Configurations/WebDriverSettings/DriverSettings.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Configurations/WebDriverSettings/DriverSettings.cs
@@ -201,7 +201,7 @@ protected void SetOptionsByPropertyNames(DriverOptions options)
}
}
- private void SetOptionByPropertyName(DriverOptions options, KeyValuePair option, Exception exception)
+ private static void SetOptionByPropertyName(DriverOptions options, KeyValuePair option, Exception exception)
{
var optionProperty = options
.GetType()
@@ -215,14 +215,14 @@ private void SetOptionByPropertyName(DriverOptions options, KeyValuePair> KnownCapabilitySetters => new Dictionary>
{
- { "binary", (options, value) => ((FirefoxOptions) options).BrowserExecutableLocation = value.ToString() },
- { "firefox_binary", (options, value) => ((FirefoxOptions) options).BrowserExecutableLocation = value.ToString() },
+ { "binary", (options, value) => ((FirefoxOptions) options).BinaryLocation = value.ToString() },
+ { "firefox_binary", (options, value) => ((FirefoxOptions) options).BinaryLocation = value.ToString() },
{ "firefox_profile", (options, value) => ((FirefoxOptions) options).Profile = new FirefoxProfileManager().GetProfile(value.ToString()) },
{ "log", (options, value) => ((FirefoxOptions) options).LogLevel = value.ToEnum() }
};
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/JsActions.cs b/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/JsActions.cs
index d5988627..b063f326 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/JsActions.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/JsActions.cs
@@ -29,9 +29,9 @@ public JsActions(IElement element, string elementType, ILocalizedLogger logger,
Logger = logger;
}
- private Browser Browser => AqualityServices.Browser;
+ private static Browser Browser => AqualityServices.Browser;
- private IElementActionRetrier ActionRetrier => AqualityServices.Get();
+ private static IElementActionRetrier ActionRetrier => AqualityServices.Get();
protected ILocalizedLogger Logger { get; }
@@ -93,7 +93,7 @@ public void ScrollIntoView()
/// Vertical coordinate
public void ScrollBy(int x, int y)
{
- LogElementAction("loc.scrolling.js");
+ LogElementAction("loc.scrolling.by.js", x, y);
ExecuteScript(JavaScript.ScrollBy, x, y);
}
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/MouseActions.cs b/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/MouseActions.cs
index c1a0e96c..3229deeb 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/MouseActions.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Elements/Actions/MouseActions.cs
@@ -6,6 +6,7 @@
using Aquality.Selenium.Core.Utilities;
using Aquality.Selenium.Core.Localization;
using Aquality.Selenium.Configurations;
+using static OpenQA.Selenium.Interactions.WheelInputDevice;
namespace Aquality.Selenium.Elements.Actions
{
@@ -49,7 +50,7 @@ public void DoubleClick()
}
///
- /// Perfroms right click on element.
+ /// Performs right click on element.
///
public void RightClick()
{
@@ -57,6 +58,39 @@ public void RightClick()
elementActionsRetrier.DoWithRetry(() => PerformAction(element => MoveToElement(element).ContextClick(element)));
}
+ ///
+ /// Scrolling page to the element.
+ ///
+ public void ScrollToElement()
+ {
+ LogElementAction("loc.scrolling");
+ elementActionsRetrier.DoWithRetry(() => PerformAction(element => new SeleniumActions(AqualityServices.Browser.Driver).ScrollToElement(element)));
+ }
+
+ ///
+ /// Scrolling page from an element.
+ ///
+ public void ScrollFromOrigin(int x, int y, int? xOffset = null, int? yOffset = null)
+ {
+ LogElementAction("loc.scrolling.by", x, y);
+ elementActionsRetrier.DoWithRetry(() =>
+ {
+ var scrollOrigin = new ScrollOrigin
+ {
+ Element = element.GetElement()
+ };
+ if (xOffset != null)
+ {
+ scrollOrigin.XOffset = xOffset.Value;
+ }
+ if (yOffset != null)
+ {
+ scrollOrigin.YOffset = yOffset.Value;
+ }
+ AqualityServices.Browser.ScrollFromOrigin(scrollOrigin, x, y);
+ });
+ }
+
///
/// Moves mouse to the element.
///
@@ -79,7 +113,7 @@ public void MoveMouseFromElement()
.MoveToElement(element, -element.Size.Width / 2, -element.Size.Height / 2)));
}
- private SeleniumActions MoveToElement(IWebElement element)
+ private static SeleniumActions MoveToElement(IWebElement element)
{
return new SeleniumActions(AqualityServices.Browser.Driver).MoveToElement(element);
}
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Elements/Element.cs b/Aquality.Selenium/src/Aquality.Selenium/Elements/Element.cs
index d77af92a..1715fb7b 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Elements/Element.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Elements/Element.cs
@@ -16,7 +16,6 @@
using ICoreElementFactory = Aquality.Selenium.Core.Elements.Interfaces.IElementFactory;
using ICoreElementFinder = Aquality.Selenium.Core.Elements.Interfaces.IElementFinder;
using ICoreElementStateProvider = Aquality.Selenium.Core.Elements.Interfaces.IElementStateProvider;
-using System.Collections.Generic;
namespace Aquality.Selenium.Elements
{
@@ -31,7 +30,7 @@ protected Element(By locator, string name, ElementState state) : base(locator, n
public override ICoreElementStateProvider State => new ElementStateProvider(Locator, ConditionalWait, Finder, LogElementState);
- protected IBrowserProfile BrowserProfile => AqualityServices.Get();
+ protected virtual IBrowserProfile BrowserProfile => AqualityServices.Get();
public JsActions JsActions => new JsActions(this, ElementType, LocalizedLogger, BrowserProfile);
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/ITextBox.cs b/Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/ITextBox.cs
index 89597e73..1c8b72a0 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/ITextBox.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Elements/Interfaces/ITextBox.cs
@@ -11,6 +11,11 @@ public interface ITextBox : IElement
/// String representation of element's value
string Value { get; }
+ ///
+ /// Clear element text.
+ ///
+ void Clear();
+
///
/// Type text in an element.
///
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Elements/TextBox.cs b/Aquality.Selenium/src/Aquality.Selenium/Elements/TextBox.cs
index 3d23e058..a2c81a00 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Elements/TextBox.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Elements/TextBox.cs
@@ -19,6 +19,13 @@ protected internal TextBox(By locator, string name, ElementState state) : base(l
public string Value => GetAttribute(Attributes.Value);
+ public void Clear()
+ {
+ LogElementAction("loc.text.clearing");
+ JsActions.HighlightElement();
+ DoWithRetry(() => GetElement().Clear());
+ }
+
public void Type(string value, bool secret = false)
{
LogElementAction("loc.text.typing", secret ? SecretMask : value);
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Forms/Form.cs b/Aquality.Selenium/src/Aquality.Selenium/Forms/Form.cs
index 0120ce80..96302311 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Forms/Form.cs
+++ b/Aquality.Selenium/src/Aquality.Selenium/Forms/Form.cs
@@ -86,6 +86,16 @@ protected Form(By locator, string name)
/// horizontal coordinate
/// vertical coordinate
public void ScrollBy(int x, int y)
+ {
+ FormElement.MouseActions.ScrollFromOrigin(x, y);
+ }
+
+ ///
+ /// Scroll form via JavaScript without scrolling entire page
+ ///
+ /// horizontal coordinate
+ /// vertical coordinate
+ public void ScrollByJs(int x, int y)
{
FormElement.JsActions.ScrollBy(x, y);
}
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/be.json b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/be.json
index 90669f5d..f7ba8b6a 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/be.json
+++ b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/be.json
@@ -66,7 +66,10 @@
"loc.movingFrom": "Адводзім курсор мышы ад элемента",
"loc.radio": "Радыёкнопка",
"loc.scrolling.center.js": "Пракручваем старонку да цэнтра элемента праз JavaScript",
- "loc.scrolling.js": "Пракручваем старонку праз JavaScript",
+ "loc.scrolling.js": "Пракручваем старонку да элемента праз JavaScript",
+ "loc.scrolling": "Пракручваем старонку да элемента",
+ "loc.scrolling.by": "Пракручваем на ({0},{1})",
+ "loc.scrolling.by.js": "Пракручваем на ({0},{1}) праз JavaScript",
"loc.selecting.value": "Выбіраем значэнне - '{0}'",
"loc.deselecting.value": "Адмяняем выбар значэння - '{0}'",
"loc.send.text": "Задаем тэкст - '{0}'",
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/en.json b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/en.json
index 03b54834..c2fd571a 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/en.json
+++ b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/en.json
@@ -66,7 +66,10 @@
"loc.movingFrom": "Moving mouse from element",
"loc.radio": "RadioButton",
"loc.scrolling.center.js": "Scrolling to the center via JavaScript",
- "loc.scrolling.js": "Scrolling via JavaScript",
+ "loc.scrolling.js": "Scrolling to element via JavaScript",
+ "loc.scrolling": "Scrolling to element",
+ "loc.scrolling.by": "Scrolling by ({0},{1})",
+ "loc.scrolling.by.js": "Scrolling by ({0},{1}) via JavaScript",
"loc.selecting.value": "Selecting value - '{0}'",
"loc.deselecting.value": "Deselecting value - '{0}'",
"loc.send.text": "Setting text - '{0}'",
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/pl.json b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/pl.json
index 9f383360..163c3986 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/pl.json
+++ b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/pl.json
@@ -66,7 +66,10 @@
"loc.movingFrom": "Przesuwanie myszy z elementu",
"loc.radio": "RadioButton",
"loc.scrolling.center.js": "Przewijanie do centrum przez JavaScript",
- "loc.scrolling.js": "Przewijanie przez JavaScript",
+ "loc.scrolling.js": "Przewijanie do elementu przez JavaScript",
+ "loc.scrolling": "Przewijanie do elementu",
+ "loc.scrolling.by": "Przewijanie o ({0},{1})",
+ "loc.scrolling.by.js": "Przewijanie o ({0},{1}) przez JavaScript",
"loc.selecting.value": "Wybieranie wartości - '{0}'",
"loc.deselecting.value": "Anulowanie wybierania wartości - '{0}'",
"loc.send.text": "Ustawianie tekstu - '{0}'",
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/ru.json b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/ru.json
index dd35bcf4..c3c7d0ed 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/ru.json
+++ b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/ru.json
@@ -66,7 +66,10 @@
"loc.movingFrom": "Сдвиг курсора с элемента",
"loc.radio": "Радиокнопка",
"loc.scrolling.center.js": "Скроллинг в центр посредством JavaScript",
- "loc.scrolling.js": "Скроллинг с помощью JavaScript",
+ "loc.scrolling.js": "Скроллинг к элементу с помощью JavaScript",
+ "loc.scrolling": "Скроллинг к элементу",
+ "loc.scrolling.by": "Скроллинг на ({0},{1})",
+ "loc.scrolling.by.js": "Скроллинг на ({0},{1}) с помощью JavaScript",
"loc.selecting.value": "Выбор значения - '{0}'",
"loc.deselecting.value": "Отмена выбора значения - '{0}'",
"loc.send.text": "Ввод текста - '{0}'",
diff --git a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/uk.json b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/uk.json
index d3850c95..3e4636be 100644
--- a/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/uk.json
+++ b/Aquality.Selenium/src/Aquality.Selenium/Resources/Localization/uk.json
@@ -66,7 +66,10 @@
"loc.movingFrom": "Переміщення миші від елемента",
"loc.radio": "Радіокнопка",
"loc.scrolling.center.js": "Прокрутка до центру за допомогою JavaScript",
- "loc.scrolling.js": "Прокрутка за допомогою JavaScript",
+ "loc.scrolling.js": "Прокрутка до елемента за допомогою JavaScript",
+ "loc.scrolling": "Прокрутка до елемента",
+ "loc.scrolling.by": "Прокрутка на ({0},{1})",
+ "loc.scrolling.by.js": "Прокрутка на ({0},{1}) за допомогою JavaScript",
"loc.selecting.value": "Вибір значення - '{0}'",
"loc.deselecting.value": "Скасування выбору значення - '{0}'",
"loc.send.text": "Встановлення тексту - '{0}'",
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Aquality.Selenium.Tests.csproj b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Aquality.Selenium.Tests.csproj
index cea9b59d..ecd0b4c9 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Aquality.Selenium.Tests.csproj
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Aquality.Selenium.Tests.csproj
@@ -29,12 +29,12 @@
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Actions/MouseActionsTests.cs b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Actions/MouseActionsTests.cs
index 2bd2736b..bd6ab983 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Actions/MouseActionsTests.cs
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Actions/MouseActionsTests.cs
@@ -42,5 +42,38 @@ public void Should_BePossibleTo_MoveToElement()
JQueryMenuForm.EnabledButton.MouseActions.MoveToElement();
Assert.That(JQueryMenuForm.IsEnabledButtonFocused, "Element should be focused after move mouse");
}
+
+ [Test]
+ public void Should_BePossibleTo_ScrollToElement()
+ {
+ var infiniteScrollForm = new InfiniteScrollForm();
+ infiniteScrollForm.Open();
+ infiniteScrollForm.WaitForPageToLoad();
+ var size = infiniteScrollForm.LastExampleLabel.Visual.Size;
+ AqualityServices.Browser.SetWindowSize(size.Width, size.Height);
+ var defaultCount = infiniteScrollForm.ExampleLabels.Count;
+ Assert.DoesNotThrow(
+ () => AqualityServices.ConditionalWait.WaitForTrue(() =>
+ {
+ infiniteScrollForm.LastExampleLabel.MouseActions.ScrollToElement();
+ return infiniteScrollForm.ExampleLabels.Count > defaultCount;
+ }), "Some examples should be added after scroll");
+ }
+
+ [Test]
+ public void Should_BePossibleTo_ScrollFromOrigin()
+ {
+ var infiniteScrollForm = new InfiniteScrollForm();
+ infiniteScrollForm.Open();
+ infiniteScrollForm.WaitForPageToLoad();
+ var defaultCount = infiniteScrollForm.ExampleLabels.Count;
+ Assert.DoesNotThrow(
+ () => AqualityServices.ConditionalWait.WaitForTrue(() =>
+ {
+ var formHeight = infiniteScrollForm.Size.Height;
+ infiniteScrollForm.LastExampleLabel.MouseActions.ScrollFromOrigin(0, formHeight);
+ return infiniteScrollForm.ExampleLabels.Count > defaultCount;
+ }), "Some examples should be added after scroll");
+ }
}
}
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/BrowserTests.cs b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/BrowserTests.cs
index 5b9bc6f8..0e11466f 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/BrowserTests.cs
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/BrowserTests.cs
@@ -200,6 +200,22 @@ public void Should_BePossibleTo_ScrollWindowBy()
}), "Some examples should be added after scroll");
}
+ [Test]
+ public void Should_BePossibleTo_ScrollWindowBy_ViaJs()
+ {
+ var infiniteScrollForm = new InfiniteScrollForm();
+ infiniteScrollForm.Open();
+ infiniteScrollForm.WaitForPageToLoad();
+ var defaultCount = infiniteScrollForm.ExampleLabels.Count;
+ Assert.DoesNotThrow(
+ () => AqualityServices.ConditionalWait.WaitForTrue(() =>
+ {
+ var formHeight = infiniteScrollForm.Size.Height;
+ AqualityServices.Browser.ScrollWindowByViaJs(0, formHeight);
+ return infiniteScrollForm.ExampleLabels.Count > defaultCount;
+ }), "Some examples should be added after scroll");
+ }
+
[Test]
public void Should_BePossibleTo_GetBrowserName()
{
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsEmulationTests.cs b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsEmulationTests.cs
index cad43bd4..fee2c299 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsEmulationTests.cs
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsEmulationTests.cs
@@ -59,11 +59,11 @@ public void Should_BePossibleTo_SetAndClearDeviceMetricsOverride_WithVersionSpec
{
void setAction(long width, long height, bool isMobile, double scaleFactor)
{
- var parameters = new OpenQA.Selenium.DevTools.V125.Emulation.SetDeviceMetricsOverrideCommandSettings
+ var parameters = new OpenQA.Selenium.DevTools.V128.Emulation.SetDeviceMetricsOverrideCommandSettings
{
- DisplayFeature = new OpenQA.Selenium.DevTools.V125.Emulation.DisplayFeature
+ DisplayFeature = new OpenQA.Selenium.DevTools.V128.Emulation.DisplayFeature
{
- Orientation = OpenQA.Selenium.DevTools.V125.Emulation.DisplayFeatureOrientationValues.Horizontal
+ Orientation = OpenQA.Selenium.DevTools.V128.Emulation.DisplayFeatureOrientationValues.Horizontal
},
Width = width,
Height = height,
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsPerformanceTests.cs b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsPerformanceTests.cs
index 21375426..25a61ea0 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsPerformanceTests.cs
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/DevToolsPerformanceTests.cs
@@ -11,7 +11,7 @@ internal class DevToolsPerformanceTests : UITest
[Test]
public void Should_BePossibleTo_CollectPerformanceMetrics()
{
- Assert.DoesNotThrowAsync(async () => await DevTools.EnablePerfomanceMonitoring(), "Should be possible to enable performance monitoring");
+ Assert.DoesNotThrowAsync(async () => await DevTools.EnablePerformanceMonitoring(), "Should be possible to enable performance monitoring");
AqualityServices.Browser.GoTo("http://www.google.com");
IDictionary metrics = null;
@@ -22,7 +22,7 @@ public void Should_BePossibleTo_CollectPerformanceMetrics()
IDictionary otherMetrics = DevTools.GetPerformanceMetrics().GetAwaiter().GetResult();
Assert.That(otherMetrics, Is.Not.EqualTo(metrics), "Some additional metrics should have been collected");
- Assert.DoesNotThrowAsync(async () => await DevTools.DisablePerfomanceMonitoring(), "Should be possible to disable performance monitoring");
+ Assert.DoesNotThrowAsync(async () => await DevTools.DisablePerformanceMonitoring(), "Should be possible to disable performance monitoring");
AqualityServices.Browser.Refresh();
metrics = DevTools.GetPerformanceMetrics().GetAwaiter().GetResult();
Assert.That(metrics, Is.Empty, "Metrics should have not been collected after performance monitoring have been disabled");
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Elements/TextBoxTests.cs b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Elements/TextBoxTests.cs
index 8f1a5ef1..104aaea7 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Elements/TextBoxTests.cs
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Elements/TextBoxTests.cs
@@ -27,6 +27,33 @@ public void Should_BePossibleTo_FocusAndType()
Assert.That(usernameTxb.Value, Is.EqualTo(text));
}
+ [Test]
+ public void Should_BePossibleTo_Clear_WhenWasEmpty()
+ {
+ var usernameTxb = authForm.UserNameTextBox;
+ usernameTxb.Clear();
+ Assert.That(usernameTxb.Value, Is.Empty);
+ }
+
+ [Test]
+ public void Should_BePossibleTo_Clear_WhenWasFilled()
+ {
+ var initialText = "initial value";
+ var usernameTxb = authForm.UserNameTextBox;
+ usernameTxb.Type(initialText);
+ usernameTxb.Clear();
+ Assert.That(usernameTxb.Value, Is.Empty);
+ }
+
+ [Test]
+ public void Should_BePossibleTo_Clear_Twice()
+ {
+ var usernameTxb = authForm.UserNameTextBox;
+ usernameTxb.Clear();
+ usernameTxb.Clear();
+ Assert.That(usernameTxb.Value, Is.Empty);
+ }
+
[Test]
public void Should_BePossibleTo_ClearAndType()
{
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Usecases/FileDownloadingTests.cs b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Usecases/FileDownloadingTests.cs
index 303212c6..d26d4e4e 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Usecases/FileDownloadingTests.cs
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/Usecases/FileDownloadingTests.cs
@@ -4,7 +4,6 @@
using NUnit.Framework;
using OpenQA.Selenium;
using System;
-using System.Collections.Generic;
namespace Aquality.Selenium.Tests.Integration.Usecases
{
diff --git a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Resources/settings.json b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Resources/settings.json
index 053ae458..794da47c 100644
--- a/Aquality.Selenium/tests/Aquality.Selenium.Tests/Resources/settings.json
+++ b/Aquality.Selenium/tests/Aquality.Selenium.Tests/Resources/settings.json
@@ -25,7 +25,7 @@
"Performance": "All"
},
"excludedArguments": [ "enable-automation" ],
- "startArguments": [],
+ "startArguments": [ "--disable-search-engine-choice-screen" ],
"pageLoadStrategy": "Normal"
},
"firefox": {
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 536a6b66..38ce301a 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -15,11 +15,12 @@ stages:
displayName: Analyse code with SonarQube
steps:
- - task: SonarCloudPrepare@1
+ - task: SonarCloudPrepare@2
displayName: 'Prepare SonarCloud analysis'
inputs:
SonarCloud: 'SonarCloud'
organization: 'aqualityautomation'
+ scannerMode: 'MSBuild'
projectKey: 'aquality-automation_aquality-selenium-dotnet'
projectName: 'aquality-selenium-dotnet'
projectVersion: '$(Build.BuildNumber)'
@@ -35,12 +36,16 @@ stages:
projects: Aquality.Selenium/Aquality.Selenium.sln
arguments: -c $(buildConfiguration)
- - task: SonarCloudAnalyze@1
+ - task: SonarCloudAnalyze@2
displayName: 'Run SonarCloud code analysis'
continueOnError: true
+ inputs:
+ jdkversion: 'JAVA_HOME_17_X64'
- - task: SonarCloudPublish@1
+ - task: SonarCloudPublish@2
displayName: 'Publish SonarCloud quality gate results'
+ inputs:
+ pollingTimeoutSec: '300'
- job: tests
displayName: Run tests