-
Notifications
You must be signed in to change notification settings - Fork 2
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
Feature/keyboard and mouse actions #12
Merged
Merged
Changes from 6 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
be4339b
add KeyboardActions for Application for #9
mialeska 1748e8d
Implement element actions to resolve #9
mialeska be6ab9a
add localization for new actions, fixed logging of Keys to fix #9.
mialeska 5023348
removed redundant .ToList() call
mialeska cc70fc9
rework container registration, fix review comments
mialeska b713e48
fix typo in the documentation
mialeska 5134446
Add setters to Application and ServiceProvider properties
mialeska 968b9ff
implemented MouseActions for custom element and for the whole applica…
mialeska dcac790
Add localization for new actions.
mialeska c94773c
Refactor ApplicationManager and Factories. Fixed Localization test
mialeska 79625bf
Rework KeyboardActions with holding/releasing a key
mialeska 2403470
try to fix Should_NotThrow_WhenHoldModifierKeys_ViaKeyboardActions test
mialeska 7cd3231
make ValueSource field protected for inherited tests
mialeska File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
67 changes: 67 additions & 0 deletions
67
Aquality.WinAppDriver/src/Aquality.WinAppDriver/Actions/IKeyboardActions.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,67 @@ | ||
namespace Aquality.WinAppDriver.Actions | ||
{ | ||
/// <summary> | ||
/// Provides methods representing basic keyboard actions. | ||
/// </summary> | ||
public interface IKeyboardActions | ||
{ | ||
/// <summary> | ||
/// Presses a key. | ||
/// </summary> | ||
/// <param name="keyToPress">The key value representing the key to press.</param> | ||
/// <remarks>The key value must be one of the values from the <see cref="OpenQA.Selenium.Keys"/> class.</remarks> | ||
/// <exception cref="System.ArgumentException">If the key sent is not is not one of: | ||
/// <see cref="OpenQA.Selenium.Keys.Shift"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Control"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Alt"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Meta"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Command"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.LeftAlt"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.LeftShift"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Shift"/> | ||
/// </exception> | ||
void PressKey(string keyToPress); | ||
|
||
/// <summary> | ||
/// Releases a key. | ||
/// </summary> | ||
/// <param name="keyToRelease">The key value representing the key to release.</param> | ||
/// <remarks>The key value must be one of the values from the <see cref="OpenQA.Selenium.Keys"/> class.</remarks> | ||
/// <exception cref="System.ArgumentException">If the key sent is not is not one of: | ||
/// <see cref="OpenQA.Selenium.Keys.Shift"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Control"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Alt"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Meta"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Command"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.LeftAlt"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.LeftShift"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Shift"/> | ||
/// </exception> | ||
void ReleaseKey(string keyToRelease); | ||
|
||
/// <summary> | ||
/// Sends a sequence of keystrokes to the target. | ||
/// </summary> | ||
/// <param name="keySequence">A string representing the keystrokes to send.</param> | ||
void SendKeys(string keySequence); | ||
|
||
/// <summary> | ||
/// Sends a sequence of keystrokes to the target, holding a specified key. | ||
/// After the action, holded key is released. | ||
/// </summary> | ||
/// <param name="keySequence">A string representing the keystrokes to send.</param> | ||
/// <param name="keyToHold">The key value representing the key to hold. | ||
/// <remarks>The key value must be one of the values from the <see cref="OpenQA.Selenium.Keys"/> class.</remarks></param> | ||
/// <exception cref="System.ArgumentException">If the key sent is not is not one of: | ||
/// <see cref="OpenQA.Selenium.Keys.Shift"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Control"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Alt"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Meta"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Command"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.LeftAlt"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.LeftShift"/>, | ||
/// <see cref="OpenQA.Selenium.Keys.Shift"/> | ||
/// </exception> | ||
void SendKeysWithKeyHold(string keySequence, string keyToHold); | ||
} | ||
} |
66 changes: 66 additions & 0 deletions
66
Aquality.WinAppDriver/src/Aquality.WinAppDriver/Actions/KeyboardActions.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,66 @@ | ||
using Aquality.Selenium.Core.Localization; | ||
using Aquality.WinAppDriver.Extensions; | ||
using OpenQA.Selenium.Appium.Windows; | ||
using System; | ||
using SeleniumActions = OpenQA.Selenium.Interactions.Actions; | ||
|
||
namespace Aquality.WinAppDriver.Actions | ||
{ | ||
/// <summary> | ||
/// Implements Keyboard actions for the whole application. | ||
/// </summary> | ||
public class KeyboardActions : IKeyboardActions | ||
{ | ||
private readonly LocalizationLogger localizationLogger; | ||
private readonly Func<WindowsDriver<WindowsElement>> windowsDriverSupplier; | ||
|
||
public KeyboardActions(LocalizationLogger localizationLogger, Func<WindowsDriver<WindowsElement>> windowsDriverSupplier) | ||
{ | ||
this.localizationLogger = localizationLogger; | ||
this.windowsDriverSupplier = windowsDriverSupplier; | ||
} | ||
|
||
public void PressKey(string keyToPress) | ||
{ | ||
LogAction("loc.keyboard.presskey", keyToPress.GetLoggableValueForKeyboardKey()); | ||
PerformAction(actions => actions.KeyDown(keyToPress)); | ||
} | ||
|
||
public void ReleaseKey(string keyToRelease) | ||
{ | ||
LogAction("loc.keyboard.releasekey", keyToRelease.GetLoggableValueForKeyboardKey()); | ||
PerformAction(actions => actions.KeyUp(keyToRelease)); | ||
} | ||
|
||
public void SendKeys(string keySequence) | ||
{ | ||
LogAction("loc.keyboard.sendkeys", keySequence); | ||
PerformAction(actions => actions.SendKeys(keySequence)); | ||
} | ||
|
||
public void SendKeysWithKeyHold(string keySequence, string keyToHold) | ||
{ | ||
LogAction("loc.keyboard.sendkeys.withkeyhold", keySequence, keyToHold.GetLoggableValueForKeyboardKey()); | ||
PerformAction(actions => actions.KeyDown(keyToHold).SendKeys(keySequence).KeyUp(keyToHold)); | ||
} | ||
|
||
/// <summary> | ||
/// Performs submitted action against new <see cref="SeleniumActions"/> object. | ||
/// </summary> | ||
/// <param name="action">Action to be performed.</param> | ||
protected virtual void PerformAction(Func<SeleniumActions, SeleniumActions> action) | ||
{ | ||
action(new SeleniumActions(windowsDriverSupplier())).Build().Perform(); | ||
} | ||
|
||
/// <summary> | ||
/// Logs keyboard action in specific format. | ||
/// </summary> | ||
/// <param name="messageKey">Key of the localized message.</param> | ||
/// <param name="args">Arguments for the localized message.</param> | ||
protected virtual void LogAction(string messageKey, params object[] args) | ||
{ | ||
localizationLogger.Info(messageKey, args); | ||
} | ||
} | ||
} |
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
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,5 +1,6 @@ | ||
using Aquality.Selenium.Core.Configurations; | ||
using Aquality.Selenium.Core.Localization; | ||
using Aquality.WinAppDriver.Actions; | ||
using Aquality.WinAppDriver.Configurations; | ||
using OpenQA.Selenium.Appium.Service; | ||
|
||
|
@@ -11,13 +12,16 @@ public class LocalApplicationFactory : ApplicationFactory | |
private readonly IDriverSettings driverSettings; | ||
private readonly ITimeoutConfiguration timeoutConfiguration; | ||
private readonly LocalizationLogger localizationLogger; | ||
private readonly IKeyboardActions keyboardActions; | ||
|
||
public LocalApplicationFactory(AppiumLocalService driverService, IDriverSettings driverSettings, ITimeoutConfiguration timeoutConfiguration, LocalizationLogger localizationLogger) : base(localizationLogger) | ||
public LocalApplicationFactory(AppiumLocalService driverService, IDriverSettings driverSettings, ITimeoutConfiguration timeoutConfiguration, LocalizationLogger localizationLogger, IKeyboardActions keyboardActions) | ||
: base(localizationLogger) | ||
{ | ||
this.driverService = driverService; | ||
this.driverSettings = driverSettings; | ||
this.timeoutConfiguration = timeoutConfiguration; | ||
this.localizationLogger = localizationLogger; | ||
this.keyboardActions = keyboardActions; | ||
} | ||
|
||
public override Application Application | ||
|
@@ -28,7 +32,7 @@ public override Application Application | |
var serviceUrl = driverService.ServiceUrl; | ||
localizationLogger.Info("loc.application.driver.service.local.start", serviceUrl); | ||
var driver = GetDriver(serviceUrl, driverSettings.AppiumOptions, timeoutConfiguration.Command); | ||
return new Application(driver, timeoutConfiguration, localizationLogger); | ||
return new Application(driver, timeoutConfiguration, localizationLogger, keyboardActions); | ||
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. It looks very strange. Why do you need to pass actions to the Application? 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. in order to use the same instance of the keyboardActions, I guess |
||
} | ||
} | ||
} | ||
|
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
87 changes: 87 additions & 0 deletions
87
Aquality.WinAppDriver/src/Aquality.WinAppDriver/Elements/Actions/KeyboardActions.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,87 @@ | ||
using Aquality.Selenium.Core.Applications; | ||
using Aquality.Selenium.Core.Localization; | ||
using Aquality.Selenium.Core.Utilities; | ||
using Aquality.WinAppDriver.Actions; | ||
using Aquality.WinAppDriver.Elements.Interfaces; | ||
using Aquality.WinAppDriver.Extensions; | ||
using OpenQA.Selenium; | ||
using System; | ||
using SeleniumActions = OpenQA.Selenium.Interactions.Actions; | ||
|
||
namespace Aquality.WinAppDriver.Elements.Actions | ||
{ | ||
/// <summary> | ||
/// Implements Keyboard actions for a specific element. | ||
mialeska marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// </summary> | ||
public class KeyboardActions : IKeyboardActions | ||
{ | ||
private readonly IElement element; | ||
private readonly string elementType; | ||
private readonly Func<IApplication> applicationSupplier; | ||
private readonly LocalizationLogger localizationLogger; | ||
private readonly ElementActionRetrier elementActionsRetrier; | ||
|
||
/// <summary> | ||
/// Instantiates Keyboard actions for a specific element. | ||
/// </summary> | ||
/// <param name="element">Target element.</param> | ||
/// <param name="elementType">Target element's type.</param> | ||
/// <param name="applicationSupplier">Method to get current application session.</param> | ||
/// <param name="localizationLogger">Logger for localized values.</param> | ||
/// <param name="elementActionsRetrier">Retrier for element actions.</param> | ||
public KeyboardActions(IElement element, string elementType, Func<IApplication> applicationSupplier, LocalizationLogger localizationLogger, ElementActionRetrier elementActionsRetrier) | ||
{ | ||
this.element = element; | ||
this.elementType = elementType; | ||
this.applicationSupplier = applicationSupplier; | ||
this.localizationLogger = localizationLogger; | ||
this.elementActionsRetrier = elementActionsRetrier; | ||
} | ||
|
||
public void PressKey(string keyToPress) | ||
{ | ||
LogElementAction("loc.keyboard.presskey", keyToPress.GetLoggableValueForKeyboardKey()); | ||
PerformAction((actions, element) => actions.KeyDown(element, keyToPress)); | ||
} | ||
|
||
public void ReleaseKey(string keyToRelease) | ||
{ | ||
LogElementAction("loc.keyboard.releasekey", keyToRelease.GetLoggableValueForKeyboardKey()); | ||
PerformAction((actions, element) => actions.KeyUp(element, keyToRelease)); | ||
} | ||
|
||
public void SendKeys(string keySequence) | ||
{ | ||
LogElementAction("loc.keyboard.sendkeys", keySequence); | ||
PerformAction((actions, element) => actions.SendKeys(element, keySequence)); | ||
} | ||
|
||
public void SendKeysWithKeyHold(string keySequence, string keyToHold) | ||
{ | ||
LogElementAction("loc.keyboard.sendkeys.withkeyhold", keySequence, keyToHold.GetLoggableValueForKeyboardKey()); | ||
PerformAction((actions, element) => actions.KeyDown(element, keyToHold).SendKeys(element, keySequence).KeyUp(element, keyToHold)); | ||
} | ||
|
||
/// <summary> | ||
/// Performs submitted action against new <see cref="SeleniumActions"/> object. | ||
/// </summary> | ||
/// <param name="action">Action to be performed.</param> | ||
protected virtual void PerformAction(Func<SeleniumActions, IWebElement, SeleniumActions> action) | ||
{ | ||
elementActionsRetrier.DoWithRetry(() => | ||
{ | ||
action(new SeleniumActions(applicationSupplier().Driver), element.GetElement()).Build().Perform(); | ||
}); | ||
} | ||
|
||
/// <summary> | ||
/// Logs element action in specific format. | ||
/// </summary> | ||
/// <param name="messageKey">Key of the localized message.</param> | ||
/// <param name="args">Arguments for the localized message.</param> | ||
protected virtual void LogElementAction(string messageKey, params object[] args) | ||
{ | ||
localizationLogger.InfoElementAction(elementType, element.Name, messageKey, args); | ||
} | ||
} | ||
} |
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
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.
Do you really need this list of Keys in summary?
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.
yes I do. Selenium has it. We either need to follow it's notation, or define a custom Enum with mapping to this values, and accept only them in our methods. I like the first variant more, but we can discuss it