├── .gitignore ├── ClientApp ├── ClientApp.csproj ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── app.config └── packages.config ├── LICENSE.md ├── README.md ├── Tests ├── AbsoluteXPath │ ├── AbsoluteXPath.csproj │ ├── AbsoluteXPath.sln │ ├── Alarms.cs │ ├── Calculator.cs │ ├── DesktopSession.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── README.md │ ├── SimpleAttributeExpression.cs │ ├── ValidXPath.cs │ ├── notepad.cs │ └── packages.config ├── Input │ ├── Input.csproj │ ├── Input.sln │ ├── MultiTouchScenarios.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── README.md │ ├── TestBase.cs │ ├── TouchScenarios.cs │ ├── app.config │ └── packages.config ├── README.md ├── UWPControls │ ├── Button.cs │ ├── CheckBox.cs │ ├── ComboBox.cs │ ├── DatePicker.cs │ ├── ProgressBar.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── README.md │ ├── RadioButton.cs │ ├── Slider.cs │ ├── TextBlock.cs │ ├── TextBox.cs │ ├── ToggleButton.cs │ ├── ToggleSwitch.cs │ ├── UWPControls.csproj │ ├── UWPControls.sln │ ├── UWPControlsBase.cs │ └── packages.config ├── WebDriverAPI │ ├── Actions.cs │ ├── ActionsPen.cs │ ├── ActionsTouch.cs │ ├── AppSessionBase │ │ ├── AlarmClockBase.cs │ │ ├── CalculatorBase.cs │ │ ├── CommonTestSettings.cs │ │ ├── EdgeBase.cs │ │ ├── Utility.cs │ │ └── WebDriverApiExtensions.cs │ ├── AppiumAppClose.cs │ ├── AppiumAppLaunch.cs │ ├── Back.cs │ ├── Element.cs │ ├── ElementActive.cs │ ├── ElementAttribute.cs │ ├── ElementClear.cs │ ├── ElementClick.cs │ ├── ElementDisplayed.cs │ ├── ElementElement.cs │ ├── ElementElements.cs │ ├── ElementEnabled.cs │ ├── ElementEquals.cs │ ├── ElementLocation.cs │ ├── ElementLocationInView.cs │ ├── ElementName.cs │ ├── ElementSelected.cs │ ├── ElementSendKeys.cs │ ├── ElementSize.cs │ ├── ElementText.cs │ ├── Elements.cs │ ├── Extensions │ │ └── WebElementExtensions.cs │ ├── Forward.cs │ ├── Location.cs │ ├── Mouse.cs │ ├── Orientation.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── README.md │ ├── Screenshot.cs │ ├── SendKeys.cs │ ├── Session.cs │ ├── Sessions.cs │ ├── Source.cs │ ├── Status.cs │ ├── Timeouts.cs │ ├── Title.cs │ ├── TouchClick.cs │ ├── TouchDoubleClick.cs │ ├── TouchDownMoveUp.cs │ ├── TouchFlick.cs │ ├── TouchLongClick.cs │ ├── TouchScroll.cs │ ├── WebDriverAPI.csproj │ ├── WebDriverAPI.sln │ ├── Window.cs │ ├── app.config │ └── packages.config └── custom.props ├── WinAppDriver.Console ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── WinAppDriver.Console.csproj ├── app.config └── packages.config ├── WinAppDriver.Server ├── NLog.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── WinAppDriver.Server.csproj ├── app.config └── packages.config ├── WinAppDriver.sln ├── WinAppDriver ├── Appium │ ├── CommandInfoRepository.cs │ └── DriverCommand.cs ├── ApplicationProcess.cs ├── Assets │ ├── AlignmentGrid.png │ ├── ApplicationIcon.png │ ├── BadgeLogo.png │ ├── Logo.png │ ├── SplashScreen.png │ ├── SquareTile150x150.png │ ├── SquareTile71x71.png │ ├── StoreLogo.png │ ├── Tiles │ │ ├── FlipCycleTileLarge.png │ │ ├── FlipCycleTileMedium.png │ │ ├── FlipCycleTileSmall.png │ │ ├── IconicTileMediumLarge.png │ │ └── IconicTileSmall.png │ └── WideLogo.png ├── Behaviors │ ├── UnexpectedAlertBehavior.cs │ └── UnexpectedAlertBehavior2.cs ├── Bootstrapper.cs ├── Command.cs ├── CommandEnvironment.cs ├── CommandEnvironmentExtensions.cs ├── CommandHandlerFactory.cs ├── CommandHandlers │ ├── ActionsCommandHandler.cs │ ├── AddCookieCommandHandler.cs │ ├── AlertHandlingCommandHandler.cs │ ├── AsyncElementCommandHandler.cs │ ├── ClearElementCommandHandler.cs │ ├── ClickElementCommandHandler.cs │ ├── CloseCommandHandler.cs │ ├── CommandHandler.cs │ ├── Css │ │ └── BackColorHandler.cs │ ├── DeleteAllCookiesCommandHandler.cs │ ├── ElementCommandHandler.cs │ ├── ElementEqualsCommandHandler.cs │ ├── ExecuteAsyncScriptCommandHandler.cs │ ├── ExecuteScriptCommandHandler.cs │ ├── FindChildElementCommandHandler.cs │ ├── FindChildElementsCommandHandler.cs │ ├── FindElementCommandHandler.cs │ ├── FindElementsCommandHandler.cs │ ├── GetActiveElementCommandHandler.cs │ ├── GetAlertTextCommandHandler.cs │ ├── GetAllCookiesCommandHandler.cs │ ├── GetCurrentUrlCommandHandler.cs │ ├── GetCurrentWindowHandleCommandHandler.cs │ ├── GetElementAttributeValueCommandHandler.cs │ ├── GetElementCssPropertyValueCommandHandler.cs │ ├── GetElementLocationCommandHandler.cs │ ├── GetElementLocationInViewCommandHandler.cs │ ├── GetElementRectCommandHandler.cs │ ├── GetElementSizeCommandHandler.cs │ ├── GetElementTagNameCommandHandler.cs │ ├── GetElementTextCommandHandler.cs │ ├── GetOrientationCommandHandler.cs │ ├── GetPageSourceCommandHandler.cs │ ├── GetTitleCommandHandler.cs │ ├── GetWindowHandlesCommandHandler.cs │ ├── GetWindowRectCommandHandler.cs │ ├── GoBackCommandHandler.cs │ ├── GoForwardCommandHandler.cs │ ├── GoToUrlCommandHandler.cs │ ├── IAsyncCommandHandler.cs │ ├── IsElementDisplayedCommandHandler.cs │ ├── IsElementEnabledCommandHandler.cs │ ├── IsElementSelectedCommandHandler.cs │ ├── MouseButtonDownCommandHandler.cs │ ├── MouseButtonUpCommandHandler.cs │ ├── MouseClickCommandHandler.cs │ ├── MouseDoubleClickCommandHandler.cs │ ├── MouseMoveCommandHandler.cs │ ├── NewSessionCommandHandler.cs │ ├── NoOpCommandHandler.cs │ ├── NotImplementedCommandHandler.cs │ ├── QuitCommandHandler.cs │ ├── RefreshCommandHandler.cs │ ├── ResizeWindowCommandHandler.cs │ ├── ScreenshotCommandHandler.cs │ ├── SendKeysCommandHandler.cs │ ├── SendKeysToActiveElementCommandHandler.cs │ ├── SetImplicitWaitTimeoutCommandHandler.cs │ ├── SetTimeoutCommandHandler.cs │ ├── SetWindowRectCommandHandler.cs │ ├── StatusCommandHandler.cs │ ├── SubmitCommandHandler.cs │ ├── SwitchToFrameCommandHandler.cs │ ├── SwitchToWindowCommandHandler.cs │ └── UnknownCommandHandler.cs ├── DriverCommand.cs ├── DriverHost.cs ├── EventHandler.cs ├── Exceptions │ ├── ElementNotDisplayedException.cs │ ├── IRemoteException.cs │ ├── InvalidParameterValueException.cs │ ├── InvalidSelectorException.cs │ ├── MissingParameterException.cs │ ├── NoSuchElementException.cs │ ├── ObsoleteElementException.cs │ └── StaleElementReferenceException.cs ├── Extensions │ ├── AutomationElementExtensions.cs │ ├── AutomationExtensions.cs │ ├── COMExceptionExtensions.cs │ ├── ControlTypeExtensions.cs │ ├── DictionaryExtensions.cs │ ├── StringExtensions.cs │ └── TreeWalkerExtensions.cs ├── Host.cs ├── Infrastructure │ ├── CacheStore.cs │ ├── ElementCache.cs │ ├── ElementCacheFactory.cs │ ├── ElementFinder.cs │ ├── ElementFinderByType.cs │ └── ElementFinders │ │ ├── ActiveElementFinder.cs │ │ └── WindowElementFinder.cs ├── Input │ ├── Devices │ │ └── Keyboard.cs │ ├── InputDeviceException.cs │ ├── Key.cs │ ├── Keyboard.cs │ ├── KeyboardActions.cs │ ├── Mouse.cs │ ├── MouseActions.cs │ ├── MouseButton.cs │ ├── MouseButtonState.cs │ ├── NamespaceDoc.cs │ ├── NativeMethods.cs │ └── SendMouseInputFlags.cs ├── JsonNetSerializer.cs ├── Package.appxmanifest ├── PngWriter │ ├── ToolStackCRCLib.cs │ ├── ToolStackPNGWriterLib.cs │ └── WritableBitmapExtensions.cs ├── Properties │ ├── AppManifest.xml │ ├── AssemblyInfo.cs │ └── WMAppManifest.xml ├── ProtocolValueJsonConverter.cs ├── Response.cs ├── SeleniumModule.cs ├── Strategies │ └── SendKeys │ │ ├── Grouped.cs │ │ ├── ISendKeysStrategy.cs │ │ ├── OneByOne.cs │ │ └── SetValue.cs ├── TextEventArgs.cs ├── Utils │ ├── NativeMethods.cs │ ├── PointComparer.cs │ └── ScreenshotCapture.cs ├── WebBrowserNavigationMonitor.cs ├── WebDriverAtoms.cs ├── WebDriverStatusCode.cs ├── WinAppDriver.csproj ├── XPath │ ├── AutomationElementTreeWalker.cs │ ├── AxisElement.cs │ ├── FormNavigator.cs │ ├── FunctionElement.cs │ ├── Functions │ │ ├── Contains.cs │ │ ├── FunctionElementBase.cs │ │ ├── FunctionFactory.cs │ │ └── StartsWith.cs │ └── Iterators │ │ ├── ChildIterator.cs │ │ ├── DescenendantIterator.cs │ │ └── IteratorBase.cs ├── app.config └── packages.config ├── XPathParser-master ├── .gitignore ├── LICENSE.txt ├── README.md ├── XPathParser.nuspec ├── XPathParser.sln ├── XPathParser │ ├── IXpathBuilder.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── XPathAxis.cs │ ├── XPathOperator.cs │ ├── XPathParser.cs │ ├── XPathParser.csproj │ ├── XPathParser.snk │ ├── XPathParserException.cs │ ├── XPathScanner.cs │ └── project.json ├── XPathParserTest │ ├── ControlWalkerBuilder.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Test.cs │ ├── XPathParserTest.csproj │ ├── XPathStringBuilder.cs │ └── XPathTreeBuilder.cs ├── appveyor.yml └── architecture.png └── libs ├── Interop.UIAutomationClient.dll ├── ManagedWinapi.dll ├── ManagedWinapiNativeHelper.dll └── UIAComWrapper.dll /ClientApp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace ClientApp 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new Form1()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ClientApp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ClientApp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ClientApp")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ba92d581-90f9-4067-bb65-dd1a71c0bd3d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ClientApp/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ClientApp.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ClientApp.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ClientApp/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ClientApp.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ClientApp/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ClientApp/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ClientApp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Karel Frajtak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Tests/AbsoluteXPath/AbsoluteXPath.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.329 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AbsoluteXPath", "AbsoluteXPath.csproj", "{971BE3D2-1EFF-4660-A8A8-C1A52966572C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {971BE3D2-1EFF-4660-A8A8-C1A52966572C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {971BE3D2-1EFF-4660-A8A8-C1A52966572C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {971BE3D2-1EFF-4660-A8A8-C1A52966572C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {971BE3D2-1EFF-4660-A8A8-C1A52966572C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {4E2EBE62-05BC-42C6-8002-CB40A0D39472} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Tests/AbsoluteXPath/DesktopSession.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2019 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using System; 18 | using OpenQA.Selenium.Appium.Windows; 19 | using OpenQA.Selenium.Remote; 20 | 21 | namespace AbsoluteXPath 22 | { 23 | public class DesktopSession 24 | { 25 | private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723/"; 26 | WindowsDriver desktopSession; 27 | 28 | public DesktopSession() 29 | { 30 | DesiredCapabilities appCapabilities = new DesiredCapabilities(); 31 | appCapabilities.SetCapability("app", "Root"); 32 | appCapabilities.SetCapability("deviceName", "WindowsPC"); 33 | desktopSession = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), appCapabilities); 34 | } 35 | 36 | ~DesktopSession() 37 | { 38 | desktopSession.Quit(); 39 | } 40 | 41 | public WindowsDriver DesktopSessionElement 42 | { 43 | get { return desktopSession; } 44 | } 45 | 46 | public WindowsElement FindElementByAbsoluteXPath(string xPath, int nTryCount = 15) 47 | { 48 | WindowsElement uiTarget = null; 49 | 50 | while (nTryCount-- > 0) 51 | { 52 | try 53 | { 54 | uiTarget = desktopSession.FindElementByXPath(xPath); 55 | } 56 | catch 57 | { 58 | } 59 | 60 | if (uiTarget != null) 61 | { 62 | break; 63 | } 64 | else 65 | { 66 | System.Threading.Thread.Sleep(2000); 67 | } 68 | } 69 | 70 | return uiTarget; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Tests/AbsoluteXPath/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("AbsoluteXPath")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("")] 9 | [assembly: AssemblyProduct("AbsoluteXPath")] 10 | [assembly: AssemblyCopyright("Copyright © 2019")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | [assembly: ComVisible(false)] 15 | 16 | [assembly: Guid("971be3d2-1eff-4660-a8a8-c1a52966572c")] 17 | 18 | // [assembly: AssemblyVersion("1.0.*")] 19 | [assembly: AssemblyVersion("1.0.0.0")] 20 | [assembly: AssemblyFileVersion("1.0.0.0")] 21 | -------------------------------------------------------------------------------- /Tests/AbsoluteXPath/README.md: -------------------------------------------------------------------------------- 1 | # AbsoluteXPath 2 | 3 | AbsoluteXPath is a sample test project that demonstrates how UIRecorder generated xpaths are used to find target elements. You can use this as a template for writing your test project. 4 | 5 | This test project highlights some common interactions below that can be put together to perform and verify various UI scenario on a modern app. 6 | - Sending click action to an element 7 | - Sending keyboard input to a text box 8 | 9 | ## Requirements 10 | 11 | - Windows 10 PC with the latest Windows 10 version (Version 1607 or later) 12 | - Microsoft Visual Studio 2015 or later 13 | 14 | ## Getting Started 15 | 16 | 1. Open `AlarmClockTest.sln` in Visual Studio 17 | 2. Select **Test** > **Windows** > **Test Explorer** 18 | 3. Select **Run All** on the test pane or through menu **Test** > **Run** > **All Tests** 19 | 20 | > Once the project is successfully built, you can use the **TestExplorer** to pick and choose the test scenario(s) to run 21 | 22 | 23 | ## Adding/Updating Test Scenario 24 | 25 | Please follow the guidelines below to maintain test reliability and conciseness: 26 | 1. Group test methods based on the UI view page such as Alarm, Stopwatch, Timer, etc. 27 | 2. Maintain original state after test runs and keep clean state in between tests when possible 28 | 3. Only add tests that provide additional value to the sample 29 | -------------------------------------------------------------------------------- /Tests/AbsoluteXPath/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Tests/Input/Input.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Input", "Input.csproj", "{E0FC5C2C-3C64-4542-A0DB-DC8059948619}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E0FC5C2C-3C64-4542-A0DB-DC8059948619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {E0FC5C2C-3C64-4542-A0DB-DC8059948619}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {E0FC5C2C-3C64-4542-A0DB-DC8059948619}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E0FC5C2C-3C64-4542-A0DB-DC8059948619}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Tests/Input/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2017 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using System.Reflection; 18 | using System.Runtime.CompilerServices; 19 | using System.Runtime.InteropServices; 20 | 21 | // General Information about an assembly is controlled through the following 22 | // set of attributes. Change these attribute values to modify the information 23 | // associated with an assembly. 24 | [assembly: AssemblyTitle("Input")] 25 | [assembly: AssemblyDescription("")] 26 | [assembly: AssemblyConfiguration("")] 27 | [assembly: AssemblyCompany("")] 28 | [assembly: AssemblyProduct("Input")] 29 | [assembly: AssemblyCopyright("Copyright © 2017")] 30 | [assembly: AssemblyTrademark("")] 31 | [assembly: AssemblyCulture("")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | [assembly: ComVisible(false)] 37 | 38 | // The following GUID is for the ID of the typelib if this project is exposed to COM 39 | [assembly: Guid("e0fc5c2c-3c64-4542-a0db-dc8059948619")] 40 | 41 | // Version information for an assembly consists of the following four values: 42 | // 43 | // Major Version 44 | // Minor Version 45 | // Build Number 46 | // Revision 47 | // 48 | // You can specify all the values or you can default the Build and Revision Numbers 49 | // by using the '*' as shown below: 50 | [assembly: AssemblyVersion("1.0.0.0")] 51 | [assembly: AssemblyFileVersion("1.0.0.0")] 52 | -------------------------------------------------------------------------------- /Tests/Input/README.md: -------------------------------------------------------------------------------- 1 | # Input 2 | 3 | Input is a collection of test scenarios that covers various input methods such as swipe and pinch multitouch gesture. 4 | 5 | The test scenarios are written against [Input](../../ApplicationUnderTests/Input) application that logs the input event received by the target element.. This application needs to be installed once in the machine you are running your test. Follow the instruction on the application [README](../../ApplicationUnderTests/Input/README.md). 6 | 7 | 8 | ## Requirements 9 | 10 | - Windows 10 PC with the latest Windows 10 version (Version 1607 or later) 11 | - Microsoft Visual Studio 2015 or later 12 | - [Input](../../ApplicationUnderTests/Input) application 13 | 14 | 15 | ## Getting Started 16 | 17 | 1. Open `Input.sln` in Visual Studio 18 | 2. Select **Test** > **Windows** > **Test Explorer** 19 | 3. Select **Run All** on the test pane or through menu **Test** > **Run** > **All Tests** 20 | 21 | > Once the project is successfully built, you can use the **TestExplorer** to pick and choose the test scenario(s) to run 22 | -------------------------------------------------------------------------------- /Tests/Input/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Tests/Input/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Tests/README.md: -------------------------------------------------------------------------------- 1 | # Windows Application Driver Tests 2 | 3 | The following tests are used to verify Windows Application Driver functionality across JSON Wire Protocol API, basic UI controls, and input interactions. 4 | 5 | | Test | Description | 6 | |----------------------------------- |----------------------------------------------- | 7 | | [WebDriverAPI](./WebDriverAPI/) | Tests all supported JSON Wire Protocol API | 8 | | [UWPControls ](./UWPControls/) | Tests various Universal Windows UI Controls | 9 | | [Input ](./Input/) | Tests various input interactions | 10 | -------------------------------------------------------------------------------- /Tests/UWPControls/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using System.Reflection; 18 | using System.Runtime.CompilerServices; 19 | using System.Runtime.InteropServices; 20 | 21 | // General Information about an assembly is controlled through the following 22 | // set of attributes. Change these attribute values to modify the information 23 | // associated with an assembly. 24 | [assembly: AssemblyTitle("UWPControls")] 25 | [assembly: AssemblyDescription("")] 26 | [assembly: AssemblyConfiguration("")] 27 | [assembly: AssemblyCompany("")] 28 | [assembly: AssemblyProduct("UWPControls")] 29 | [assembly: AssemblyCopyright("Copyright © 2016 Microsoft Corporation")] 30 | [assembly: AssemblyTrademark("")] 31 | [assembly: AssemblyCulture("")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | [assembly: ComVisible(false)] 37 | 38 | // The following GUID is for the ID of the typelib if this project is exposed to COM 39 | [assembly: Guid("0dfb274b-8d24-401b-949b-51493ee6fd12")] 40 | 41 | // Version information for an assembly consists of the following four values: 42 | // 43 | // Major Version 44 | // Minor Version 45 | // Build Number 46 | // Revision 47 | // 48 | // You can specify all the values or you can default the Build and Revision Numbers 49 | // by using the '*' as shown below: 50 | // [assembly: AssemblyVersion("1.0.*")] 51 | [assembly: AssemblyVersion("1.0.0.0")] 52 | [assembly: AssemblyFileVersion("1.0.0.0")] 53 | -------------------------------------------------------------------------------- /Tests/UWPControls/README.md: -------------------------------------------------------------------------------- 1 | # UWPControls 2 | 3 | UWPControls is a collection of test scenarios that covers basic interactions with [Universal Windows Platform controls (UI elements)](https://docs.microsoft.com/en-us/windows/uwp/controls-and-patterns/). Use this as a reference on how to interact with certain UWP controls you have in your application. 4 | 5 | The test scenarios are written against [AppUIBasics](../../ApplicationUnderTests/AppUIBasics) application that contains all UWP basic controls. This application needs to be installed once in the machine you are running your test. Follow the instruction on the application [README](../../ApplicationUnderTests/AppUIBasics/README.md). 6 | 7 | 8 | ## Requirements 9 | 10 | - Windows 10 PC with the latest Windows 10 version (Version 1607 or later) 11 | - Microsoft Visual Studio 2015 or later 12 | - [AppUIBasics](../../ApplicationUnderTests/AppUIBasics) application 13 | 14 | 15 | ## Getting Started 16 | 17 | 1. Open `UWPControls.sln` in Visual Studio 18 | 2. Select **Test** > **Windows** > **Test Explorer** 19 | 3. Select **Run All** on the test pane or through menu **Test** > **Run** > **All Tests** 20 | 21 | Note: The target application AppUIBasics will need to have been built and deployed [using the instructions here](https://github.com/Microsoft/WinAppDriver/tree/master/ApplicationUnderTests/AppUIBasics) prior to running the tests. 22 | 23 | > Once the project is successfully built, you can use the **TestExplorer** to pick and choose the test scenario(s) to run 24 | 25 | 26 | ## Controls 27 | 28 | - [Button ](./Button.cs) 29 | - [CheckBox ](./CheckBox.cs) 30 | - [ComboBox ](./ComboBox.cs) 31 | - [DatePicker ](./DatePicker.cs) 32 | - [ProgressBar ](./ProgressBar.cs) 33 | - [RadioButton ](./RadioButton.cs) 34 | - [Slider ](./Slider.cs) 35 | - [TextBlock ](./TextBlock.cs) 36 | - [TextBox ](./TextBox.cs) 37 | - [ToggleButton](./ToggleButton.cs) 38 | - [ToggleSwitch](./ToggleSwitch.cs) 39 | 40 | 41 | ## Adding/Updating Test Scenario 42 | 43 | Please follow the guidelines below to maintain test reliability and reduce test execution time: 44 | 1. Provide a complete set of interactions (if applicable) for each new control 45 | 2. Aim for simple and reliable scenario using the least amount of test steps 46 | 3. Reuse existing application session when possible to reduce unnecessary application re-launching 47 | -------------------------------------------------------------------------------- /Tests/UWPControls/UWPControls.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UWPControls", "UWPControls.csproj", "{0DFB274B-8D24-401B-949B-51493EE6FD12}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0DFB274B-8D24-401B-949B-51493EE6FD12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {0DFB274B-8D24-401B-949B-51493EE6FD12}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {0DFB274B-8D24-401B-949B-51493EE6FD12}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {0DFB274B-8D24-401B-949B-51493EE6FD12}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Tests/UWPControls/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/AppSessionBase/WebDriverApiExtensions.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2017 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using OpenQA.Selenium.Appium.Windows; 18 | using System; 19 | 20 | namespace WebDriverAPI 21 | { 22 | static class WebDriverApiExtensions 23 | { 24 | internal static WindowsElement FindCalculatorTitleByAccessibilityId(this WindowsDriver session) 25 | { 26 | WindowsElement element; 27 | try 28 | { 29 | element = session.FindElementByAccessibilityId("AppName"); 30 | } 31 | catch (InvalidOperationException) 32 | { 33 | element = session.FindElementByAccessibilityId("AppNameTitle"); 34 | } 35 | return element; 36 | } 37 | 38 | internal static void DismissAlarmDialogIfThere(this WindowsDriver session) 39 | { 40 | try 41 | { 42 | session.FindElementByAccessibilityId("SecondaryButton").Click(); 43 | } 44 | catch (InvalidOperationException) 45 | { 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/AppiumAppClose.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | using OpenQA.Selenium.Appium.Windows; 19 | using System; 20 | using System.Threading; 21 | 22 | namespace WebDriverAPI 23 | { 24 | [TestClass] 25 | public class AppiumAppClose 26 | { 27 | private WindowsDriver session = null; 28 | 29 | [TestCleanup] 30 | public void TestCleanup() 31 | { 32 | if (session != null) 33 | { 34 | session.Quit(); 35 | session = null; 36 | } 37 | } 38 | 39 | private void CloseApplication(string applicationId) 40 | { 41 | session = Utility.CreateNewSession(applicationId); 42 | Assert.IsNotNull(session.SessionId); 43 | Assert.AreNotEqual(string.Empty, session.Title); 44 | Assert.AreNotEqual(string.Empty, session.CurrentWindowHandle); 45 | Assert.IsTrue(session.WindowHandles.Count > 0); 46 | 47 | session.CloseApp(); 48 | 49 | Assert.IsNotNull(session.SessionId); 50 | Assert.AreEqual(0, session.WindowHandles.Count); 51 | 52 | try 53 | { 54 | session.CloseApp(); // Attempt to close already closed app 55 | Assert.Fail("Exception should have been thrown"); 56 | } 57 | catch (InvalidOperationException exception) 58 | { 59 | Assert.AreEqual(ErrorStrings.NoSuchWindow, exception.Message); 60 | } 61 | } 62 | 63 | [TestMethod] 64 | public void Close_ClassicApp() 65 | { 66 | CloseApplication(CommonTestSettings.NotepadAppId); 67 | } 68 | 69 | [TestMethod] 70 | public void Close_ModernApp() 71 | { 72 | CloseApplication(CommonTestSettings.CalculatorAppId); 73 | } 74 | 75 | [TestMethod] 76 | public void Close_SystemApp() 77 | { 78 | CloseApplication(CommonTestSettings.ExplorerAppId); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Extensions/WebElementExtensions.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace WebDriverAPI.Extensions 10 | { 11 | public static class WebElementExtensions 12 | { 13 | public static IWebElement FindElementByName(this IWebElement element, string name) 14 | { 15 | 16 | } 17 | 18 | public static IWebElement FindElementByTagName(this IWebElement element, string tagName) 19 | { 20 | 21 | } 22 | 23 | public static IWebElement FindElementByXPath(this IWebElement element, string tagName) 24 | { 25 | 26 | } 27 | 28 | public static IWebElement FindElementByAccessibilityId(this IWebElement element, string tagName) 29 | { 30 | 31 | } 32 | 33 | public static ReadOnlyCollection FindElementsByXPath(this IWebElement element, string tagName) 34 | { 35 | 36 | } 37 | 38 | public static ReadOnlyCollection FindElementsByClassName(this IWebElement element, string tagName) 39 | { 40 | 41 | } 42 | 43 | public static ReadOnlyCollection FindElementsByAccessibilityId(this IWebElement element, string tagName) 44 | { 45 | 46 | } 47 | 48 | public static ReadOnlyCollection FindElementsByName(this IWebElement element, string tagName) 49 | { 50 | 51 | } 52 | 53 | public static ReadOnlyCollection FindElementsById(this IWebElement element, string tagName) 54 | { 55 | 56 | } 57 | 58 | public static ReadOnlyCollection FindElementsByTagName(this IWebElement element, string tagName) 59 | { 60 | 61 | } 62 | 63 | public static ReadOnlyCollection FindElementsByCssSelector(this IWebElement element, string tagName) 64 | { 65 | 66 | } 67 | 68 | public static ReadOnlyCollection FindElementsByLinkText(this IWebElement element, string tagName) 69 | { 70 | 71 | } 72 | 73 | public static ReadOnlyCollection FindElementsByPartialLinkText(this IWebElement element, string tagName) 74 | { 75 | 76 | } 77 | 78 | public static OpenQA.Selenium.Screenshot GetScreenshot(this IWebElement element) 79 | { 80 | 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Location.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | 19 | namespace WebDriverAPI 20 | { 21 | [TestClass] 22 | public class Location : AlarmClockBase 23 | { 24 | [ClassInitialize] 25 | public static void ClassInitialize(TestContext context) 26 | { 27 | Setup(context); 28 | } 29 | 30 | [ClassCleanup] 31 | public static void ClassCleanup() 32 | { 33 | TearDown(); 34 | } 35 | 36 | [TestMethod] 37 | public void GetLocation() 38 | { 39 | OpenQA.Selenium.Appium.Location geoLocation = session.Location; 40 | Assert.IsNotNull(geoLocation.Altitude); 41 | Assert.IsNotNull(geoLocation.Latitude); 42 | Assert.IsNotNull(geoLocation.Longitude); 43 | Assert.IsTrue(System.Math.Abs(geoLocation.Latitude) <= 90); 44 | Assert.IsTrue(System.Math.Abs(geoLocation.Longitude) <= 180); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Orientation.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | using System; 19 | 20 | namespace WebDriverAPI 21 | { 22 | [TestClass] 23 | public class Orientation : CalculatorBase 24 | { 25 | [ClassInitialize] 26 | public static void ClassInitialize(TestContext context) 27 | { 28 | Setup(context); 29 | } 30 | 31 | [ClassCleanup] 32 | public static void ClassCleanup() 33 | { 34 | TearDown(); 35 | } 36 | 37 | [TestMethod] 38 | public void GetOrientation() 39 | { 40 | var orientation = session.Orientation; 41 | Assert.IsNotNull(orientation); 42 | Assert.IsTrue(orientation == OpenQA.Selenium.ScreenOrientation.Landscape || orientation == OpenQA.Selenium.ScreenOrientation.Portrait); 43 | } 44 | 45 | [TestMethod] 46 | public void GetOrientationError_NoSuchWindow() 47 | { 48 | try 49 | { 50 | var orientation = Utility.GetOrphanedSession().Orientation; 51 | Assert.Fail("Exception should have been thrown"); 52 | } 53 | catch (InvalidOperationException exception) 54 | { 55 | Assert.AreEqual(ErrorStrings.NoSuchWindow, exception.Message); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using System.Reflection; 18 | using System.Runtime.CompilerServices; 19 | using System.Runtime.InteropServices; 20 | 21 | // General Information about an assembly is controlled through the following 22 | // set of attributes. Change these attribute values to modify the information 23 | // associated with an assembly. 24 | [assembly: AssemblyTitle("WebDriverAPI")] 25 | [assembly: AssemblyDescription("")] 26 | [assembly: AssemblyConfiguration("")] 27 | [assembly: AssemblyCompany("")] 28 | [assembly: AssemblyProduct("WebDriverAPI")] 29 | [assembly: AssemblyCopyright("Copyright © 2016 Microsoft Corporation")] 30 | [assembly: AssemblyTrademark("")] 31 | [assembly: AssemblyCulture("")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | [assembly: ComVisible(false)] 37 | 38 | // The following GUID is for the ID of the typelib if this project is exposed to COM 39 | [assembly: Guid("81529391-98a1-478c-98a2-e59a2e826796")] 40 | 41 | // Version information for an assembly consists of the following four values: 42 | // 43 | // Major Version 44 | // Minor Version 45 | // Build Number 46 | // Revision 47 | // 48 | // You can specify all the values or you can default the Build and Revision Numbers 49 | // by using the '*' as shown below: 50 | // [assembly: AssemblyVersion("1.0.*")] 51 | [assembly: AssemblyVersion("1.0.0.0")] 52 | [assembly: AssemblyFileVersion("1.0.0.0")] 53 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/README.md: -------------------------------------------------------------------------------- 1 | # WebDriverAPI 2 | 3 | WebDriverAPI is a collection of test scenarios that covers every WebDriver command supported by Windows Application Driver. Use this as a reference on how to invoke each command in the test script. While these tests are written in C#, corresponding commands in other Selenium supported language bindings should map to the same API endpoint. 4 | 5 | The test scenarios are written against Windows 10 built-in apps such as **Calculator**, **Alarms & Clock**, **Notepad**, **File Explorer**, and **Microsoft Edge Browser**. Therefore these tests can simply be run on Windows 10 PC running Windows Application Driver. 6 | 7 | 8 | ## Requirements 9 | 10 | - Windows 10 PC with the latest Windows 10 version (Version 1607 or later) 11 | - Microsoft Visual Studio 2015 or later 12 | 13 | 14 | ## Getting Started 15 | 16 | 1. Open `WebDriverAPI.sln` in Visual Studio 17 | 2. Select **Test** > **Windows** > **Test Explorer** 18 | 3. Select **Run All** on the test pane or through menu **Test** > **Run** > **All Tests** 19 | 20 | > Once the project is successfully built, you can use the **TestExplorer** to pick and choose the test scenario(s) to run 21 | 22 | 23 | ## Command Summary 24 | 25 | Please refer to [here](/./././Docs/SupportedAPIs.md) for an updated list of supported WinAppDriver commands. 26 | 27 | ## Command Reference 28 | 29 | These tests are written to verify each API endpoint behavior and error values as specified in [JSON Wire Protocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol) document. 30 | 31 | 32 | ## Adding/Updating Test Scenario 33 | 34 | Please follow the guidelines below to maintain test reliability and reduce test execution time: 35 | 1. Avoid duplicating test scenario that uses the same code path 36 | 2. Aim for simple and reliable scenario using the least amount of test steps 37 | 3. Write test against Windows 10 built-in apps only to avoid requiring extra installation 38 | 4. Reuse existing application session when possible to reduce unnecessary application re-launching 39 | 5. Group test methods accordingly by naming them with the existing convention. E.g. 40 | - `ClickElement` 41 | - `ClickElementError_NoSuchWindow` 42 | - `ClickElementError_StaleElement` 43 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Source.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using System; 18 | using System.Xml; 19 | using Microsoft.VisualStudio.TestTools.UnitTesting; 20 | 21 | namespace WebDriverAPI 22 | { 23 | [TestClass] 24 | public class Source : AlarmClockBase 25 | { 26 | [ClassInitialize] 27 | public static void ClassInitialize(TestContext context) 28 | { 29 | Setup(context); 30 | } 31 | 32 | [ClassCleanup] 33 | public static void ClassCleanup() 34 | { 35 | TearDown(); 36 | } 37 | 38 | [TestMethod] 39 | public void GetSource() 40 | { 41 | var source = session.PageSource; 42 | Assert.AreNotEqual(source.Length, 0); 43 | XmlDocument xmlDoc = new XmlDocument(); 44 | xmlDoc.LoadXml(source); 45 | Assert.IsTrue(xmlDoc.SelectNodes("//Button").Count > 0); 46 | } 47 | 48 | [TestMethod] 49 | public void GetSourceError_NoSuchWindow() 50 | { 51 | try 52 | { 53 | var source = Utility.GetOrphanedSession().PageSource; 54 | Assert.Fail("Exception should have been thrown"); 55 | } 56 | catch (InvalidOperationException exception) 57 | { 58 | Assert.AreEqual(ErrorStrings.NoSuchWindow, exception.Message); 59 | } 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Status.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using System.IO; 18 | using System.Net; 19 | using Microsoft.VisualStudio.TestTools.UnitTesting; 20 | using Newtonsoft.Json.Linq; 21 | 22 | namespace WebDriverAPI 23 | { 24 | [TestClass] 25 | public class Status 26 | { 27 | [TestMethod] 28 | public void GetStatus() 29 | { 30 | var request = WebRequest.Create(CommonTestSettings.WindowsApplicationDriverUrl + "/status/"); 31 | request.Method = "GET"; 32 | using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) 33 | { 34 | var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); 35 | JObject responseObject = JObject.Parse(responseString); 36 | 37 | JToken buildToken = responseObject["build"]; 38 | Assert.IsNotNull(buildToken); 39 | Assert.IsNotNull(buildToken["version"]); 40 | Assert.IsNotNull(buildToken["revision"]); 41 | Assert.IsNotNull(buildToken["time"]); 42 | 43 | JToken osToken = responseObject["os"]; 44 | Assert.IsNotNull(osToken); 45 | Assert.IsNotNull(osToken["arch"]); 46 | Assert.AreEqual(osToken["name"], "windows"); 47 | Assert.IsNotNull(osToken["version"]); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/Title.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | using OpenQA.Selenium.Appium.Windows; 19 | using System; 20 | 21 | namespace WebDriverAPI 22 | { 23 | [TestClass] 24 | public class Title 25 | { 26 | private WindowsDriver session = null; 27 | 28 | [TestCleanup] 29 | public void TestCleanup() 30 | { 31 | if (session != null) 32 | { 33 | session.Quit(); 34 | session = null; 35 | } 36 | } 37 | 38 | [TestMethod] 39 | public void GetTitle_ClassicApp() 40 | { 41 | session = Utility.CreateNewSession(CommonTestSettings.NotepadAppId); 42 | Assert.IsNotNull(session); 43 | Assert.AreEqual("Untitled - Notepad", session.Title); 44 | } 45 | 46 | [TestMethod] 47 | public void GetTitle_Desktop() 48 | { 49 | session = Utility.CreateNewSession(CommonTestSettings.DesktopAppId); 50 | Assert.IsNotNull(session); 51 | Assert.IsTrue(session.Title.StartsWith("Desktop")); 52 | } 53 | 54 | [TestMethod] 55 | public void GetTitle_ModernApp() 56 | { 57 | session = Utility.CreateNewSession(CommonTestSettings.CalculatorAppId); 58 | Assert.IsNotNull(session); 59 | Assert.IsTrue(session.Title.Contains("Calculator")); 60 | } 61 | 62 | [TestMethod] 63 | public void GetTitleError_NoSuchWindow() 64 | { 65 | try 66 | { 67 | var title = Utility.GetOrphanedSession().Title; 68 | Assert.Fail("Exception should have been thrown"); 69 | } 70 | catch (InvalidOperationException exception) 71 | { 72 | Assert.AreEqual(ErrorStrings.NoSuchWindow, exception.Message); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/TouchClick.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | using OpenQA.Selenium; 19 | using System; 20 | using System.Threading; 21 | 22 | namespace WebDriverAPI 23 | { 24 | [TestClass] 25 | public class TouchClick : EdgeBase 26 | { 27 | [ClassInitialize] 28 | public static void ClassInitialize(TestContext context) 29 | { 30 | Setup(context); 31 | } 32 | 33 | [ClassCleanup] 34 | public static void ClassCleanup() 35 | { 36 | TearDown(); 37 | } 38 | 39 | [TestMethod] 40 | public void TouchSingleTap() 41 | { 42 | session.FindElementByAccessibilityId("addressEditBox").SendKeys(Keys.Alt + 'd' + Keys.Alt + CommonTestSettings.EdgeAboutFlagsURL + Keys.Enter); 43 | Thread.Sleep(TimeSpan.FromSeconds(2)); 44 | var originalTitle = session.Title; 45 | Assert.AreNotEqual(string.Empty, originalTitle); 46 | 47 | // Navigate to Edge blank page to create navigation history 48 | session.FindElementByAccessibilityId("addressEditBox").SendKeys(Keys.Alt + 'd' + Keys.Alt + CommonTestSettings.EdgeAboutBlankURL + Keys.Enter); 49 | Thread.Sleep(TimeSpan.FromSeconds(2)); 50 | Assert.AreNotEqual(originalTitle, session.Title); 51 | 52 | // Perform single tap touch on the back button 53 | touchScreen.SingleTap(session.FindElementByName("Back").Coordinates); 54 | Thread.Sleep(TimeSpan.FromSeconds(2)); 55 | 56 | // Make sure the page you went to is the page we started on 57 | Assert.AreEqual(originalTitle, session.Title); 58 | } 59 | 60 | [TestMethod] 61 | public void TouchSingleTapError_StaleElement() 62 | { 63 | try 64 | { 65 | // Perform single tap touch on stale element 66 | touchScreen.SingleTap(GetStaleElement().Coordinates); 67 | Assert.Fail("Exception should have been thrown"); 68 | } 69 | catch (InvalidOperationException exception) 70 | { 71 | Assert.AreEqual(ErrorStrings.StaleElementReference, exception.Message); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/TouchFlick.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | using OpenQA.Selenium; 19 | using System; 20 | using System.Threading; 21 | 22 | namespace WebDriverAPI 23 | { 24 | [TestClass] 25 | public class TouchFlick : EdgeBase 26 | { 27 | [ClassInitialize] 28 | public static void ClassInitialize(TestContext context) 29 | { 30 | Setup(context); 31 | } 32 | 33 | [ClassCleanup] 34 | public static void ClassCleanup() 35 | { 36 | TearDown(); 37 | } 38 | 39 | [TestMethod] 40 | public void TouchFlick_Arbitrary() 41 | { 42 | // Navigate to Edge about:flags page 43 | session.FindElementByAccessibilityId("addressEditBox").SendKeys(Keys.Alt + 'd' + Keys.Alt + CommonTestSettings.EdgeAboutFlagsURL + Keys.Enter); 44 | Thread.Sleep(TimeSpan.FromSeconds(1)); 45 | 46 | // Use the reset all button on Edge about:flags page as a reference element 47 | var resetAllFlagsButton = session.FindElementByAccessibilityId("ResetAllFlags"); 48 | Assert.IsNotNull(resetAllFlagsButton); 49 | Assert.IsTrue(resetAllFlagsButton.Displayed); 50 | 51 | // Perform flick up touch action to scroll the page down hiding the Homepage link element from the view 52 | // Good value typically goes around 160 - 200 pixels with diminishing delta on the bigger values 53 | touchScreen.Flick(0, 180); 54 | Thread.Sleep(TimeSpan.FromSeconds(3)); 55 | Assert.IsFalse(resetAllFlagsButton.Displayed); 56 | 57 | // Perform flick down touch action to scroll the page up restoring the button element into the view 58 | touchScreen.Flick(0, -360); 59 | Thread.Sleep(TimeSpan.FromSeconds(3)); 60 | Assert.IsTrue(resetAllFlagsButton.Displayed); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Tests/WebDriverAPI/TouchLongClick.cs: -------------------------------------------------------------------------------- 1 | //****************************************************************************** 2 | // 3 | // Copyright (c) 2016 Microsoft Corporation. All rights reserved. 4 | // 5 | // This code is licensed under the MIT License (MIT). 6 | // 7 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 | // THE SOFTWARE. 14 | // 15 | //****************************************************************************** 16 | 17 | using Microsoft.VisualStudio.TestTools.UnitTesting; 18 | using System; 19 | using System.Threading; 20 | 21 | namespace WebDriverAPI 22 | { 23 | [TestClass] 24 | public class TouchLongClick : AlarmClockBase 25 | { 26 | [ClassInitialize] 27 | public static void ClassInitialize(TestContext context) 28 | { 29 | Setup(context); 30 | } 31 | 32 | [ClassCleanup] 33 | public static void ClassCleanup() 34 | { 35 | TearDown(); 36 | } 37 | 38 | [TestMethod] 39 | public void TouchLongTap() 40 | { 41 | // Create a new test alarm 42 | string alarmName = "LongTapTest"; 43 | DeletePreviouslyCreatedAlarmEntry(alarmName); 44 | AddAlarmEntry(alarmName); 45 | Thread.Sleep(TimeSpan.FromSeconds(3)); 46 | 47 | var alarmEntries = session.FindElementsByXPath($"//ListItem[starts-with(@Name, \"{alarmName}\")]"); 48 | Assert.IsNotNull(alarmEntries); 49 | Assert.AreEqual(1, alarmEntries.Count); 50 | 51 | // Open a the context menu on the alarm entry using long tap (press and hold) action and click delete 52 | touchScreen.LongPress(alarmEntries[0].Coordinates); 53 | Thread.Sleep(TimeSpan.FromSeconds(3)); 54 | session.FindElementByName("Delete").Click(); 55 | Thread.Sleep(TimeSpan.FromSeconds(3)); 56 | 57 | alarmEntries = session.FindElementsByXPath($"//ListItem[starts-with(@Name, \"{alarmName}\")]"); 58 | Assert.IsNotNull(alarmEntries); 59 | Assert.AreEqual(0, alarmEntries.Count); 60 | } 61 | 62 | [TestMethod] 63 | public void TouchLongTapError_StaleElement() 64 | { 65 | try 66 | { 67 | // Perform long press touch on stale element 68 | touchScreen.LongPress(GetStaleElement().Coordinates); 69 | Assert.Fail("Exception should have been thrown"); 70 | } 71 | catch (InvalidOperationException exception) 72 | { 73 | Assert.AreEqual(ErrorStrings.StaleElementReference, exception.Message); 74 | } 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/WebDriverAPI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebDriverAPI", "WebDriverAPI.csproj", "{81529391-98A1-478C-98A2-E59A2E826796}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {81529391-98A1-478C-98A2-E59A2E826796}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {81529391-98A1-478C-98A2-E59A2E826796}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {81529391-98A1-478C-98A2-E59A2E826796}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {81529391-98A1-478C-98A2-E59A2E826796}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Tests/WebDriverAPI/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Tests/custom.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tests\$(MSBuildProjectName) 5 | 6 | -------------------------------------------------------------------------------- /WinAppDriver.Console/Program.cs: -------------------------------------------------------------------------------- 1 | using Cavalo.Server; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace Cavalo.Console 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | using (var host = new Host(new Uri("http://localhost:12345"))) 14 | { 15 | host.Start(); 16 | System.Console.WriteLine("Running on http://localhost:12345"); 17 | System.Console.ReadLine(); 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WinAppDriver.Console/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Cavalo.Console")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Cavalo.Console")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9425de29-c2d6-4a22-b90d-c099767c303d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /WinAppDriver.Console/WinAppDriver.Console.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9425DE29-C2D6-4A22-B90D-C099767C303D} 8 | Exe 9 | WinAppDriver.Console 10 | WinAppDriver.Console 11 | v4.0 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | ..\packages\Selenium.WebDriver.3.14.0\lib\net40\WebDriver.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {E061097B-700E-4340-824D-F33805C4ED5B} 54 | WinAppDriver.Server 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /WinAppDriver.Console/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WinAppDriver.Console/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /WinAppDriver.Server/NLog.config: -------------------------------------------------------------------------------- 1 |  2 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /WinAppDriver.Server/Program.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | 4 | namespace ClientApp 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [MTAThread] 12 | static void Main(string[] args) 13 | { 14 | var uri = new Uri("http://localhost:4444"); 15 | 16 | if (args.Length == 1) 17 | { 18 | if (!Uri.TryCreate(args[0], UriKind.Absolute, out uri)) 19 | { 20 | Console.Out.WriteLine($"Provided value '{args[0]}' is not a valid URI."); 21 | return; 22 | } 23 | } 24 | 25 | var commandDispatcher = new DriverHost(uri); 26 | commandDispatcher.Start(); 27 | Console.ReadLine(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /WinAppDriver.Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WinAppDriver.Server")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WinAppDriver.Server")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e061097b-700e-4340-824d-f33805c4ed5b")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /WinAppDriver.Server/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WinAppDriver.Server/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /WinAppDriver/Appium/CommandInfoRepository.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium.Remote; 2 | 3 | namespace WinAppDriver.Server.Appium 4 | { 5 | public class CommandInfoRepository 6 | { 7 | public static void AddAppiumCommands(W3CWireProtocolCommandInfoRepository commandInfoRepository) 8 | { 9 | commandInfoRepository.TryAddCommand( 10 | DriverCommand.CloseApp, 11 | new CommandInfo("POST", @"/session/{sessionId}/appium/app/close")); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WinAppDriver/Appium/DriverCommand.cs: -------------------------------------------------------------------------------- 1 | namespace WinAppDriver.Server.Appium 2 | { 3 | /// 4 | /// 5 | /// 6 | public static class DriverCommand 7 | { 8 | /// 9 | /// Represents a close application command 10 | /// 11 | public static readonly string CloseApp = "closeApp"; 12 | } 13 | } -------------------------------------------------------------------------------- /WinAppDriver/Assets/AlignmentGrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/AlignmentGrid.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/ApplicationIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/ApplicationIcon.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/BadgeLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/BadgeLogo.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/Logo.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/SplashScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/SplashScreen.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/SquareTile150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/SquareTile150x150.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/SquareTile71x71.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/SquareTile71x71.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/StoreLogo.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/Tiles/FlipCycleTileLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/Tiles/FlipCycleTileLarge.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/Tiles/FlipCycleTileMedium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/Tiles/FlipCycleTileMedium.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/Tiles/FlipCycleTileSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/Tiles/FlipCycleTileSmall.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/Tiles/IconicTileMediumLarge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/Tiles/IconicTileMediumLarge.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/Tiles/IconicTileSmall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/Tiles/IconicTileSmall.png -------------------------------------------------------------------------------- /WinAppDriver/Assets/WideLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/WinAppDriver/Assets/WideLogo.png -------------------------------------------------------------------------------- /WinAppDriver/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using Nancy; 2 | using Nancy.Bootstrapper; 3 | using Nancy.TinyIoc; 4 | 5 | namespace WinAppDriver.Server 6 | { 7 | public class Bootstrapper : DefaultNancyBootstrapper 8 | { 9 | private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); 10 | 11 | protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context) 12 | { 13 | } 14 | 15 | protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) 16 | { 17 | base.RequestStartup(container, pipelines, context); 18 | 19 | pipelines.OnError += (_, ex) => 20 | { 21 | Logger.Error(ex, "Unexpected error has occurred."); 22 | return null; 23 | }; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /WinAppDriver/CommandEnvironmentExtensions.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | 3 | namespace WinAppDriver 4 | { 5 | public static class CommandEnvironmentExtensions 6 | { 7 | public static Strategies.SendKeys.SendKeyStrategyType GetSendKeyStrategyType(this CommandEnvironment commandEnvironment) 8 | { 9 | var sendKeyStrategy = commandEnvironment.GetDesiredCapabilityValue("sendKeyStrategy") ?? "oneByOne"; 10 | switch (sendKeyStrategy.ToString().ToLowerInvariant()) 11 | { 12 | case "grouped": 13 | return Strategies.SendKeys.SendKeyStrategyType.Grouped; 14 | case "setvalue": 15 | return Strategies.SendKeys.SendKeyStrategyType.SetValue; 16 | } 17 | return Strategies.SendKeys.SendKeyStrategyType.OneByOne; 18 | } 19 | 20 | public static Strategies.SendKeys.ISendKeyStrategy GetSendKeyStrategy(this CommandEnvironment commandEnvironment) 21 | { 22 | var sendKeyStrategy = commandEnvironment.GetSendKeyStrategyType(); 23 | switch (sendKeyStrategy) 24 | { 25 | case Strategies.SendKeys.SendKeyStrategyType.Grouped: 26 | return new Strategies.SendKeys.Grouped(); 27 | case Strategies.SendKeys.SendKeyStrategyType.SetValue: 28 | return new Strategies.SendKeys.SetValue(); 29 | } 30 | return new Strategies.SendKeys.OneByOne(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/ActionsCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Runtime.InteropServices; 5 | using WinAppDriver.Extensions; 6 | using WinAppDriver.Input; 7 | 8 | namespace WinAppDriver.Server.CommandHandlers 9 | { 10 | internal class ActionsCommandHandler : CommandHandler 11 | { 12 | [DllImport("USER32.DLL")] 13 | public static extern bool SetForegroundWindow(IntPtr hWnd); 14 | 15 | public override Response Execute(CommandEnvironment commandEnvironment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 16 | { 17 | if (!parameters.TryGetValue("actions", out object o)) 18 | { 19 | return Response.CreateMissingParametersResponse("actions"); 20 | } 21 | 22 | var numberOfRetries = 10; 23 | Exception e = null; 24 | while (numberOfRetries-- >= 0) 25 | { 26 | if (cancellationToken.IsCancellationRequested) 27 | { 28 | return null; 29 | } 30 | 31 | try 32 | { 33 | SetForegroundWindow(commandEnvironment.WindowHandle); 34 | commandEnvironment.Window.SetFocus(); 35 | e = null; 36 | break; 37 | } 38 | catch (COMException comEx) 39 | { 40 | e = comEx; 41 | 42 | if (comEx.IsTimeout()) 43 | { 44 | System.Threading.Thread.Sleep(250); 45 | continue; 46 | } 47 | 48 | throw; 49 | } 50 | } 51 | 52 | if (e != null) 53 | { 54 | throw e; 55 | } 56 | 57 | try 58 | { 59 | var strategy = new Strategies.SendKeys.OneByOne(); 60 | return strategy.Execute(commandEnvironment, parameters, cancellationToken); 61 | } 62 | finally 63 | { 64 | Microsoft.Test.Input.Mouse.Reset(); 65 | Microsoft.Test.Input.Keyboard.Reset(); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/AsyncElementCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using System.Windows.Automation; 4 | using WinAppDriver.Exceptions; 5 | 6 | namespace WinAppDriver.Server.CommandHandlers 7 | { 8 | /// 9 | /// Provides the base class for asynchronous handling for the commands. 10 | /// 11 | internal abstract class AsyncElementCommandHandler : ElementCommandHandler, IAsyncCommandHandler 12 | { 13 | public Task ExecuteAsync(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 14 | { 15 | if (!parameters.TryGetValue(_parameterName, out object id)) 16 | { 17 | throw new MissingParameterException(_parameterName); 18 | } 19 | 20 | var element = environment.Cache.GetElement(id); 21 | if (element != null) 22 | { 23 | return GetResponseAsync(element, environment, parameters, cancellationToken); 24 | } 25 | 26 | throw new NoSuchElementException(); 27 | } 28 | 29 | protected virtual Task GetResponseAsync(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 30 | { 31 | return new Task(() => 32 | { 33 | return TryGetResponse(automationElement, environment, parameters, cancellationToken); 34 | }, cancellationToken); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/ClearElementCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Linq; 30 | using System.Text; 31 | using System.Threading.Tasks; 32 | using System.Windows.Automation; 33 | using WinAppDriver.Extensions; 34 | 35 | namespace WinAppDriver.Server.CommandHandlers 36 | { 37 | /// 38 | /// Provides handling for the clear element command. 39 | /// 40 | internal class ClearElementCommandHandler : ElementCommandHandler 41 | { 42 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 43 | { 44 | automationElement.SetText(""); 45 | return Response.CreateSuccessResponse(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/CloseCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | 4 | namespace WinAppDriver.Server.CommandHandlers 5 | { 6 | /// 7 | /// Provides handling for the close command. 8 | /// 9 | internal class CloseCommandHandler : CommandHandler 10 | { 11 | /// 12 | /// Closes the current window 13 | /// 14 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 15 | { 16 | var hwnd = environment.WindowHandle; 17 | if (hwnd == System.IntPtr.Zero) 18 | { 19 | return Response.CreateErrorResponse(WebDriverStatusCode.NoSuchWindow, $"Currently selected window has been closed"); 20 | } 21 | 22 | var window = environment.Cache.AutomationElement; 23 | if (window.TryGetCurrentPattern(WindowPattern.Pattern, out object pattern) && pattern is WindowPattern windowPattern) 24 | { 25 | environment.CloseWindow(hwnd); 26 | windowPattern.Close(); 27 | return Response.CreateSuccessResponse(); 28 | } 29 | 30 | return Response.CreateErrorResponse(WebDriverStatusCode.UnhandledError, "Cannot close current window."); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/CommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | using System.Threading; 29 | 30 | namespace WinAppDriver.Server.CommandHandlers 31 | { 32 | /// 33 | /// Provides the base class for handling for the commands. 34 | /// 35 | internal abstract class CommandHandler 36 | { 37 | protected bool _unexpectedAlertCheckRequired = true; 38 | 39 | public bool UnexpectedAlertCheckRequired => _unexpectedAlertCheckRequired; 40 | 41 | /// 42 | /// Executes the command. 43 | /// 44 | /// The to use in executing the command. 45 | /// The containing the command parameters. 46 | /// Cancellation token 47 | /// The JSON serialized string representing the command response. 48 | public abstract Response Execute(CommandEnvironment environment, Dictionary parameters, CancellationToken cancellationToken); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/Css/BackColorHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Runtime.InteropServices; 4 | using System.Windows.Automation; 5 | 6 | namespace WinAppDriver.Server.CommandHandlers.Css 7 | { 8 | public class BackColorHandler 9 | { 10 | public Response GetResponse(AutomationElement automationElement) 11 | { 12 | if (automationElement.TryGetCurrentPattern(TextPattern.Pattern, out var pattern)) 13 | { 14 | if (pattern is TextPattern textPattern) 15 | { 16 | var bgColor = textPattern.DocumentRange.GetAttributeValue(TextPattern.BackgroundColorAttribute); 17 | return Response.CreateSuccessResponse(bgColor); 18 | } 19 | } 20 | 21 | var rect = automationElement.Current.BoundingRectangle; 22 | var x = (int)rect.X + 2; 23 | var y = (int)rect.Y + 2; 24 | var hWnd = new IntPtr(automationElement.Current.NativeWindowHandle); 25 | var color = GetPixelColor(hWnd, x, y); 26 | return Response.CreateSuccessResponse("#" + color.Name); 27 | } 28 | 29 | [DllImport("gdi32.dll")] 30 | private static extern int BitBlt(IntPtr srchDc, int srcX, int srcY, int srcW, int srcH, IntPtr desthDc, int destX, int destY, int op); 31 | 32 | private static Color GetPixelColor(IntPtr hwnd, int x, int y) 33 | { 34 | using (Bitmap screenPixel = new Bitmap(1, 1)) 35 | { 36 | using (Graphics gdest = Graphics.FromImage(screenPixel)) 37 | { 38 | using (Graphics gsrc = Graphics.FromHwnd(hwnd)) 39 | { 40 | IntPtr hsrcdc = gsrc.GetHdc(); 41 | IntPtr hdc = gdest.GetHdc(); 42 | BitBlt(hdc, 0, 0, 1, 1, hsrcdc, x, y, (int)CopyPixelOperation.SourceCopy); 43 | gdest.ReleaseHdc(); 44 | gsrc.ReleaseHdc(); 45 | } 46 | } 47 | 48 | return screenPixel.GetPixel(0, 0); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/DeleteAllCookiesCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace WinAppDriver.Server.CommandHandlers 30 | { 31 | /// 32 | /// Provides handling for the get all cookies command. 33 | /// 34 | internal class DeleteAllCookiesCommandHandler : CommandHandler 35 | { 36 | /// 37 | /// Executes the command. 38 | /// 39 | /// The to use in executing the command. 40 | /// The containing the command parameters. 41 | /// The JSON serialized string representing the command response. 42 | public override Response Execute(CommandEnvironment environment, Dictionary parameters) 43 | { 44 | return Response.CreateSuccessResponse(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/FindElementCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace WinAppDriver.Server.CommandHandlers 4 | { 5 | /// 6 | /// Provides handling for the find element command. 7 | /// 8 | internal class FindElementCommandHandler : CommandHandler 9 | { 10 | /// 11 | /// Executes the command. 12 | /// 13 | /// The to use in executing the command. 14 | /// The containing the command parameters. 15 | /// The JSON serialized string representing the command response. 16 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 17 | { 18 | return new FindChildElementCommandHandler().TryGetResponse(environment.Cache.AutomationElement, environment, parameters, cancellationToken); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/FindElementsCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace WinAppDriver.Server.CommandHandlers 30 | { 31 | /// 32 | /// Provides handling for the find elements command. 33 | /// 34 | internal class FindElementsCommandHandler : CommandHandler 35 | { 36 | /// 37 | /// Executes the command. 38 | /// 39 | /// The to use in executing the command. 40 | /// The containing the command parameters. 41 | /// The JSON serialized string representing the command response. 42 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 43 | { 44 | return new FindChildElementsCommandHandler().TryGetResponse(environment.Cache.AutomationElement, environment, parameters, cancellationToken); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetAlertTextCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Collections.Generic; 3 | using WinAppDriver.XPath.Iterators; 4 | using System.Windows.Automation; 5 | using System; 6 | using WinAppDriver.Extensions; 7 | using WinAppDriver.Utils; 8 | 9 | namespace WinAppDriver.Server.CommandHandlers 10 | { 11 | internal class GetAlertTextCommandHandler : CommandHandler 12 | { 13 | public GetAlertTextCommandHandler() 14 | { 15 | _unexpectedAlertCheckRequired = false; 16 | } 17 | 18 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 19 | { 20 | var modalWindow = environment.GetModalWindow(cancellationToken); 21 | if (modalWindow == null) 22 | { 23 | return Response.CreateErrorResponse(WebDriverStatusCode.NoAlertPresent, string.Empty); 24 | } 25 | 26 | var enumerable = new DescendantIterator(modalWindow, false, cancellationToken).Cast() 27 | .Where(el => el.Current.ControlType == ControlType.Text || el.Current.ControlType == ControlType.Edit) 28 | .OrderBy(el => el.Current.BoundingRectangle.TopLeft, new PointComparer()); 29 | 30 | var alertText = string.Join(Environment.NewLine, enumerable.Select(el => el.GetText())); 31 | 32 | return Response.CreateSuccessResponse(alertText); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetCurrentWindowHandleCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace WinAppDriver.Server.CommandHandlers 30 | { 31 | /// 32 | /// Provides handling for the get window handles command. 33 | /// 34 | internal class GetCurrentWindowHandleCommandHandler : CommandHandler 35 | { 36 | /// 37 | /// Executes the command. 38 | /// 39 | /// The to use in executing the command. 40 | /// The containing the command parameters. 41 | /// The JSON serialized string representing the command response. 42 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 43 | { 44 | return Response.CreateSuccessResponse(CommandEnvironment.GlobalWindowHandle); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementAttributeValueCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | using System.Linq; 29 | using System.Windows.Automation; 30 | using WinAppDriver.Extensions; 31 | 32 | namespace WinAppDriver.Server.CommandHandlers 33 | { 34 | /// 35 | /// Provides handling for the get attribute command. 36 | /// 37 | internal class GetElementAttributeValueCommandHandler : ElementCommandHandler 38 | { 39 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 40 | { 41 | var attributeName = parameters.FirstOrDefault(p => p.Key.Equals("name", System.StringComparison.InvariantCultureIgnoreCase)) 42 | .Value?.ToString().Trim(); 43 | if (string.IsNullOrEmpty(attributeName)) 44 | { 45 | return Response.CreateMissingParametersResponse("name"); 46 | } 47 | 48 | var value = automationElement.GetAutomationElementPropertyValue(attributeName.ToString()); 49 | return Response.CreateSuccessResponse(value); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementCssPropertyValueCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Windows.Automation; 30 | 31 | namespace WinAppDriver.Server.CommandHandlers 32 | { 33 | /// 34 | /// Provides handling for the get CSS property value command. 35 | /// 36 | internal class GetElementCssPropertyValueCommandHandler : ElementCommandHandler 37 | { 38 | /// 39 | /// Provides handling for the get element CSS property value command. 40 | /// 41 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 42 | { 43 | if (!parameters.TryGetValue("name", out var name)) 44 | { 45 | return Response.CreateMissingParametersResponse("name"); 46 | } 47 | 48 | var propertyName = name?.ToString() ?? string.Empty; 49 | switch (propertyName) 50 | { 51 | case "background-color": 52 | return new Css.BackColorHandler().GetResponse(automationElement); 53 | } 54 | 55 | throw new NotSupportedException(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementLocationCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | using System.Windows.Automation; 29 | 30 | namespace WinAppDriver.Server.CommandHandlers 31 | { 32 | /// 33 | /// Provides handling for the get element location command. 34 | /// 35 | internal class GetElementLocationCommandHandler : ElementCommandHandler 36 | { 37 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 38 | { 39 | var rect = automationElement.Current.BoundingRectangle; 40 | return Response.CreateSuccessResponse(new { x = (int)rect.Left, y = (int)rect.Top, width = (int)rect.Width, height = (int)rect.Height }); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementLocationInViewCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace WinAppDriver.Server.CommandHandlers 30 | { 31 | /// 32 | /// Provides handling for the get element location command. 33 | /// 34 | internal class GetElementLocationInViewCommandHandler : CommandHandler 35 | { 36 | /// 37 | /// Executes the command. 38 | /// 39 | /// The to use in executing the command. 40 | /// The containing the command parameters. 41 | /// The JSON serialized string representing the command response. 42 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 43 | { 44 | throw new System.NotImplementedException("getElementLocationInView"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementRectCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | 4 | namespace WinAppDriver.Server.CommandHandlers 5 | { 6 | /// 7 | /// Provides handling for the get element rect command. 8 | /// 9 | internal class GetElementRectCommandHandler : ElementCommandHandler 10 | { 11 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 12 | { 13 | var rect = automationElement.Current.BoundingRectangle; 14 | return Response.CreateSuccessResponse(new { x = (int)rect.Left, y = (int)rect.Top, width = (int)rect.Width, height = (int)rect.Height }); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementSizeCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | 4 | namespace WinAppDriver.Server.CommandHandlers 5 | { 6 | /// 7 | /// Provides handling for the get element size command. 8 | /// 9 | internal class GetElementSizeCommandHandler : ElementCommandHandler 10 | { 11 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 12 | { 13 | var rect = automationElement.Current.BoundingRectangle; 14 | return Response.CreateSuccessResponse(new { width = (int)rect.Width, height = (int)rect.Height }); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementTagNameCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | using WinAppDriver.Extensions; 4 | 5 | namespace WinAppDriver.Server.CommandHandlers 6 | { 7 | /// 8 | /// Provides handling for the get element text command. 9 | /// 10 | internal class GetElementTagNameCommandHandler : ElementCommandHandler 11 | { 12 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 13 | { 14 | var value = (ControlType)automationElement.GetAutomationElementPropertyValue("ControlType"); 15 | return Response.CreateSuccessResponse(value.ProgrammaticName); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetElementTextCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | using WinAppDriver.Extensions; 4 | 5 | namespace WinAppDriver.Server.CommandHandlers 6 | { 7 | /// 8 | /// Provides handling for the get element text command. 9 | /// 10 | internal class GetElementTextCommandHandler : ElementCommandHandler 11 | { 12 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 13 | { 14 | return Response.CreateSuccessResponse(automationElement.GetText()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetTitleCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using System.Windows.Automation; 4 | using WinAppDriver.Extensions; 5 | 6 | namespace WinAppDriver.Server.CommandHandlers 7 | { 8 | internal class GetTitleCommandHandler : ElementCommandHandler 9 | { 10 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, CancellationToken cancellationToken) 11 | { 12 | if (parameters.TryGetValue(_parameterName, out object id)) 13 | { 14 | return base.Execute(environment, parameters, cancellationToken); 15 | } 16 | 17 | return TryGetResponse(environment.RootElement, environment, parameters, cancellationToken); 18 | } 19 | 20 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 21 | { 22 | return Response.CreateSuccessResponse(automationElement.GetWindowCaption()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/GetWindowRectCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace WinAppDriver.Server.CommandHandlers 4 | { 5 | /// 6 | /// Provides handling for the get window rect command. 7 | /// 8 | internal class GetWindowRectCommandHandler : CommandHandler 9 | { 10 | /// 11 | /// Executes the command. 12 | /// 13 | /// The to use in executing the command. 14 | /// The containing the command parameters. 15 | /// The JSON serialized string representing the command response. 16 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 17 | { 18 | var rect = environment.Cache.AutomationElement.Current.BoundingRectangle; 19 | return Response.CreateSuccessResponse(new { x = (int)rect.Left, y = (int)rect.Top, width = (int)rect.Width, height = (int)rect.Height }); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/IAsyncCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace WinAppDriver.Server.CommandHandlers 7 | { 8 | /// 9 | /// Provides the base class for handling for the commands. 10 | /// 11 | internal interface IAsyncCommandHandler 12 | { 13 | /// 14 | /// Executes the command. 15 | /// 16 | /// The to use in executing the command. 17 | /// The containing the command parameters. 18 | /// The JSON serialized string representing the command response. 19 | Task ExecuteAsync(CommandEnvironment environment, Dictionary parameters, CancellationToken cancellationToken); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/IsElementDisplayedCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | 4 | namespace WinAppDriver.Server.CommandHandlers 5 | { 6 | /// 7 | /// Provides handling for the is element displayed command. 8 | /// 9 | internal class IsElementDisplayedCommandHandler : ElementCommandHandler 10 | { 11 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 12 | { 13 | return Response.CreateSuccessResponse(!automationElement.Current.IsOffscreen); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/IsElementEnabledCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Automation; 3 | using WinAppDriver.Extensions; 4 | 5 | namespace WinAppDriver.Server.CommandHandlers 6 | { 7 | internal class IsElementEnabledCommandHandler : ElementCommandHandler 8 | { 9 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 10 | { 11 | // walk the tree up to be sure all element ancestors are enabled 12 | do 13 | { 14 | var isEnabled = automationElement.GetAutomationElementPropertyValue("IsEnabled"); 15 | if (!(bool)isEnabled) 16 | { 17 | return Response.CreateSuccessResponse(isEnabled); 18 | } 19 | 20 | automationElement = TreeWalker.RawViewWalker.GetParent(automationElement); 21 | } 22 | while (automationElement != null); 23 | 24 | return Response.CreateSuccessResponse(true); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/IsElementSelectedCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Automation; 4 | 5 | namespace WinAppDriver.Server.CommandHandlers 6 | { 7 | /// 8 | /// Provides handling for the is element selected command. 9 | /// 10 | internal class IsElementSelectedCommandHandler : ElementCommandHandler 11 | { 12 | protected override Response GetResponse(AutomationElement automationElement, CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 13 | { 14 | if (!automationElement.TryGetCurrentPattern(SelectionItemPattern.Pattern, out var selectionItemPattern)) 15 | { 16 | return Response.CreateSuccessResponse(false); 17 | } 18 | 19 | return Response.CreateSuccessResponse(((SelectionItemPattern)selectionItemPattern).Current.IsSelected); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/MouseButtonDownCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Automation; 5 | using WinAppDriver.Input; 6 | 7 | namespace WinAppDriver.Server.CommandHandlers 8 | { 9 | /// 10 | /// Provides handling for the mouse button down command. 11 | /// 12 | internal class MouseButtonDownCommandHandler : CommandHandler 13 | { 14 | /// 15 | /// Executes the command. 16 | /// 17 | /// The to use in executing the command. 18 | /// The containing the command parameters. 19 | /// The JSON serialized string representing the command response. 20 | public override Response Execute(CommandEnvironment commandEnvironment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 21 | { 22 | if (!parameters.TryGetValue("button", out var button)) 23 | { 24 | button = 0; 25 | } 26 | 27 | AutomationElement.FromHandle(commandEnvironment.WindowHandle).SetFocus(); 28 | var actions = new JArray{ 29 | new JObject 30 | { 31 | ["type"] = "pointerDown", 32 | ["button"] = JToken.FromObject(button) 33 | } 34 | }; 35 | 36 | new MouseActions(new JArray(actions.ToArray()), commandEnvironment).Execute(); 37 | 38 | return Response.CreateSuccessResponse(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/MouseButtonUpCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Automation; 5 | using WinAppDriver.Input; 6 | 7 | namespace WinAppDriver.Server.CommandHandlers 8 | { 9 | /// 10 | /// Provides handling for the mouse button up command. 11 | /// 12 | internal class MouseButtonUpCommandHandler : CommandHandler 13 | { 14 | /// 15 | /// Executes the command. 16 | /// 17 | /// The to use in executing the command. 18 | /// The containing the command parameters. 19 | /// The JSON serialized string representing the command response. 20 | public override Response Execute(CommandEnvironment commandEnvironment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 21 | { 22 | if (!parameters.TryGetValue("button", out var button)) 23 | { 24 | button = 0; 25 | } 26 | 27 | AutomationElement.FromHandle(commandEnvironment.WindowHandle).SetFocus(); 28 | var actions = new JArray{ 29 | new JObject 30 | { 31 | ["type"] = "pointerUp", 32 | ["button"] = JToken.FromObject(button) 33 | } 34 | }; 35 | 36 | new MouseActions(new JArray(actions.ToArray()), commandEnvironment).Execute(); 37 | 38 | return Response.CreateSuccessResponse(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/NoOpCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Linq; 30 | using System.Text; 31 | using System.Threading; 32 | using System.Threading.Tasks; 33 | 34 | using Newtonsoft.Json; 35 | 36 | namespace WinAppDriver.Server.CommandHandlers 37 | { 38 | /// 39 | /// Provides the base class for handling implemented, but non-operational commands. 40 | /// 41 | internal class NoOpCommandHandler : CommandHandler 42 | { 43 | /// 44 | /// Executes the command. 45 | /// 46 | /// The to use in executing the command. 47 | /// The containing the command parameters. 48 | /// The JSON serialized string representing the command response. 49 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 50 | { 51 | return Response.CreateSuccessResponse(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/QuitCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System.Collections.Generic; 28 | 29 | namespace WinAppDriver.Server.CommandHandlers 30 | { 31 | /// 32 | /// Provides handling for the quit command. 33 | /// 34 | internal class QuitCommandHandler : CommandHandler 35 | { 36 | public QuitCommandHandler() 37 | { 38 | _unexpectedAlertCheckRequired = false; 39 | } 40 | 41 | /// 42 | /// Disposes the session. 43 | /// 44 | /// The to use in executing the command. 45 | /// The containing the command parameters. 46 | /// The JSON serialized string representing the command response. 47 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 48 | { 49 | environment.Dispose(); 50 | return Response.CreateSuccessResponse(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/SetWindowRectCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.InteropServices; 4 | using System.Windows.Automation; 5 | 6 | namespace WinAppDriver.Server.CommandHandlers 7 | { 8 | /// 9 | /// Provides handling for the set window rect/size command. 10 | /// 11 | internal class SetWindowRectCommandHandler : CommandHandler 12 | { 13 | /// 14 | /// Executes the command. 15 | /// 16 | /// The to use in executing the command. 17 | /// The containing the command parameters. 18 | /// The JSON serialized string representing the command response. 19 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 20 | { 21 | if (!parameters.TryGetValue("width", out var width)) 22 | { 23 | return Response.CreateMissingParametersResponse("width"); 24 | } 25 | 26 | if (!parameters.TryGetValue("height", out var height)) 27 | { 28 | return Response.CreateMissingParametersResponse("height"); 29 | } 30 | 31 | Resize(environment.Cache.AutomationElement, int.Parse(width.ToString()), int.Parse(height.ToString())); 32 | 33 | return Response.CreateSuccessResponse(); 34 | } 35 | 36 | // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx 37 | [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 38 | private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, int flags); 39 | 40 | private const int SWP_NOSIZE = 0x0001; 41 | private const int SWP_NOMOVE = 0x0002; 42 | private const int SWP_NOZORDER = 0x0004; 43 | 44 | public static void Resize(AutomationElement window, int width, int height) 45 | { 46 | SetWindowPos(window, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER); 47 | } 48 | 49 | public static void Move(AutomationElement window, int x, int y) 50 | { 51 | SetWindowPos(window, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); 52 | } 53 | 54 | public static void Move(AutomationElement window, int x, int y, int width, int height) 55 | { 56 | SetWindowPos(window, x, y, width, height, SWP_NOZORDER); 57 | } 58 | 59 | private static void SetWindowPos(AutomationElement window, int x, int y, int width, int height, int flags) 60 | { 61 | var handle = new IntPtr(window.Current.NativeWindowHandle); 62 | SetWindowPos(handle, IntPtr.Zero, x, y, width, height, flags); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/SubmitCommandHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Linq; 30 | using System.Text; 31 | using System.Threading.Tasks; 32 | 33 | namespace WinAppDriver.Server.CommandHandlers 34 | { 35 | /// 36 | /// Provides handling for the submit element command. 37 | /// 38 | internal class SubmitCommandHandler : CommandHandler 39 | { 40 | /// 41 | /// Executes the command. 42 | /// 43 | /// The to use in executing the command. 44 | /// The containing the command parameters. 45 | /// The JSON serialized string representing the command response. 46 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken) 47 | { 48 | object element; 49 | if (!parameters.TryGetValue("ID", out element)) 50 | { 51 | return Response.CreateMissingParametersResponse("ID"); 52 | } 53 | 54 | throw new NotImplementedException(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /WinAppDriver/CommandHandlers/UnknownCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | 4 | namespace WinAppDriver.Server.CommandHandlers 5 | { 6 | internal class UnknownCommandHandler : CommandHandler 7 | { 8 | public override Response Execute(CommandEnvironment environment, Dictionary parameters, CancellationToken cancellationToken) 9 | { 10 | var method = parameters["method"]; 11 | var uri = parameters["uri"]; 12 | return Response.CreateErrorResponse(WebDriverStatusCode.UnknownCommand, $"{method} request to '{uri}' cannot be handled (not supported)."); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/DriverHost.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | 4 | namespace WinAppDriver.Server 5 | { 6 | public class DriverHost 7 | { 8 | private readonly Uri _uri; 9 | private Host _host; 10 | 11 | private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); 12 | 13 | public DriverHost(Uri uri) 14 | { 15 | _uri = uri; 16 | } 17 | 18 | public void Start() 19 | { 20 | try 21 | { 22 | _host = new Host(_uri); 23 | _host.Start(); 24 | Logger.Info($"Server started at {_uri}"); 25 | } 26 | catch (Exception e) 27 | { 28 | Logger.Error(e); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /WinAppDriver/EventHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Automation; 7 | 8 | namespace WinAppDriver 9 | { 10 | public class EventHandler 11 | { 12 | public static IDisposable RegisterHandler(AutomationEvent automationEvent, AutomationElement automationElement, AutomationEventHandler automationEventHandler) 13 | { 14 | return new Handler(automationEvent, automationElement, automationEventHandler); 15 | } 16 | 17 | private class Handler : IDisposable//, IUIAutomationEventHandler, IUIAutomationStructureChangedEventHandler 18 | { 19 | private AutomationEventHandler _handler; 20 | private readonly AutomationElement _automationElement; 21 | private readonly AutomationEvent _automationEvent; 22 | 23 | public Handler(AutomationEvent automationEvent, AutomationElement automationElement, AutomationEventHandler automationEventHandler) 24 | { 25 | _automationEvent = automationEvent; 26 | _automationElement = automationElement; 27 | _handler = automationEventHandler; 28 | 29 | Automation.AddAutomationEventHandler(_automationEvent, _automationElement, TreeScope.Element, _handler); 30 | } 31 | 32 | public void Dispose() 33 | { 34 | Automation.RemoveAutomationEventHandler(_automationEvent, _automationElement, _handler); 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/ElementNotDisplayedException.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | 4 | namespace WinAppDriver.Exceptions 5 | { 6 | public class ElementNotDisplayedException : Exception, IRemoteException 7 | { 8 | public ElementNotDisplayedException(string message = null) : base(message) { } 9 | 10 | public Response GetResponse() 11 | { 12 | return Response.CreateErrorResponse(WebDriverStatusCode.ElementNotDisplayed, Message); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/IRemoteException.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | 3 | namespace WinAppDriver.Exceptions 4 | { 5 | public interface IRemoteException 6 | { 7 | Response GetResponse(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/InvalidParameterValueException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WinAppDriver.Exceptions 8 | { 9 | public class InvalidParameterValueException : Exception 10 | { 11 | public InvalidParameterValueException(string name, object value, Type type, Exception innerException) 12 | : base($"InvalidParameterValueException {name} {value} {type}", innerException) 13 | { 14 | 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/InvalidSelectorException.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | 4 | namespace WinAppDriver.Exceptions 5 | { 6 | public class InvalidSelectorException : Exception, IRemoteException 7 | { 8 | public InvalidSelectorException(string message = null) : base(message) { } 9 | 10 | public Response GetResponse() 11 | { 12 | return Response.CreateErrorResponse(WebDriverStatusCode.InvalidSelector /*32*/, Message); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/MissingParameterException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WinAppDriver.Exceptions 8 | { 9 | public class MissingParameterException : Exception 10 | { 11 | public MissingParameterException(string parameterName) 12 | { 13 | 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/NoSuchElementException.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | 4 | namespace WinAppDriver.Exceptions 5 | { 6 | public class NoSuchElementException : Exception, IRemoteException 7 | { 8 | public NoSuchElementException(string message = null) : base(message) { } 9 | 10 | public Response GetResponse() 11 | { 12 | return Response.CreateErrorResponse(WebDriverStatusCode.NoSuchElement, Message, "No such element found"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/ObsoleteElementException.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | 4 | namespace WinAppDriver.Exceptions 5 | { 6 | public class ObsoleteElementException : Exception, IRemoteException 7 | { 8 | public ObsoleteElementException(string message = null) : base(message) { } 9 | 10 | public Response GetResponse() 11 | { 12 | return Response.CreateErrorResponse(WebDriverStatusCode.ObsoleteElement, Message); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/Exceptions/StaleElementReferenceException.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | 4 | namespace WinAppDriver.Exceptions 5 | { 6 | public class StaleElementReferenceException : Exception, IRemoteException 7 | { 8 | public StaleElementReferenceException(string message = null) : base(message) { } 9 | 10 | public Response GetResponse() 11 | { 12 | return Response.CreateErrorResponse(WebDriverStatusCode.ObsoleteElement, "An element command failed because the referenced element is no longer attached to the DOM."); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/Extensions/AutomationElementExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Automation; 7 | 8 | namespace WinAppDriver.Extensions 9 | { 10 | public static class AutomationElementExtensions 11 | { 12 | public static bool IsModalWindow(this AutomationElement automationElement) 13 | { 14 | return (bool)automationElement.GetCurrentPropertyValue(WindowPattern.IsModalProperty); 15 | } 16 | 17 | public static bool IsTopMostWindow(this AutomationElement automationElement) 18 | { 19 | return (bool)automationElement.GetCurrentPropertyValue(WindowPattern.IsTopmostProperty); 20 | } 21 | 22 | public static bool IsBlockedByModalWindow(this AutomationElement automationElement) 23 | { 24 | var value = (WindowInteractionState)automationElement.GetCurrentPropertyValue(WindowPattern.WindowInteractionStateProperty); 25 | return value == WindowInteractionState.BlockedByModalWindow; 26 | } 27 | 28 | public static IEnumerable GetChildren(this AutomationElement automationElement, System.Threading.CancellationToken cancellationToken) 29 | { 30 | var child = TreeWalker.ControlViewWalker.GetFirstChild(automationElement, cancellationToken); 31 | while (child != null) 32 | { 33 | if (cancellationToken.IsCancellationRequested) 34 | { 35 | yield break; 36 | } 37 | 38 | yield return child; 39 | child = TreeWalker.ControlViewWalker.GetNextSibling(child); 40 | } 41 | } 42 | 43 | public static bool IsStale(this AutomationElement automationElement) 44 | { 45 | return automationElement.Current.BoundingRectangle.Width == 0 46 | && automationElement.Current.BoundingRectangle.Height == 0; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /WinAppDriver/Extensions/COMExceptionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace WinAppDriver.Extensions 9 | { 10 | public static class COMExceptionExtensions 11 | { 12 | public static bool IsTimeout(this COMException comEx) 13 | { 14 | // Operation timed out. (Exception from HRESULT: 0x80131505) 15 | return comEx.Message.StartsWith("Operation timed out") || comEx.Message.Contains("0x80131505"); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WinAppDriver/Extensions/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using WinAppDriver.Exceptions; 4 | 5 | namespace WinAppDriver.Extensions 6 | { 7 | public static class DictionaryExtensions 8 | { 9 | public static T GetParameterValue(this Dictionary parameters, string parameterName) 10 | { 11 | if (!parameters.TryGetValue(parameterName, out var value)) 12 | { 13 | throw new MissingParameterException(parameterName); 14 | } 15 | 16 | try 17 | { 18 | return (T)Convert.ChangeType(value, typeof(T)); 19 | } 20 | catch (Exception ex) 21 | { 22 | throw new InvalidParameterValueException(parameterName, value, typeof(T), ex); 23 | } 24 | } 25 | 26 | public static bool TryGetParameterValue(this Dictionary parameters, string parameterName, out T parameterValue) 27 | { 28 | parameterValue = default(T); 29 | 30 | if (!parameters.TryGetValue(parameterName, out var value)) 31 | { 32 | return false; 33 | } 34 | 35 | try 36 | { 37 | parameterValue = (T)Convert.ChangeType(value, typeof(T)); 38 | return true; 39 | } 40 | catch 41 | { 42 | return false; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /WinAppDriver/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Exceptions; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using System.Windows.Automation; 8 | 9 | namespace WinAppDriver.Extensions 10 | { 11 | public static class StringExtensions 12 | { 13 | private static Dictionary _controlTypeCache = new Dictionary(); 14 | public static ControlType AsControlType(this string value) 15 | { 16 | value = value.ToLowerInvariant(); 17 | if (value == "textbox") 18 | { 19 | value = "edit"; 20 | } 21 | 22 | if (value == "label") 23 | { 24 | value = "text"; 25 | } 26 | 27 | if (_controlTypeCache.TryGetValue(value, out var ct)) 28 | { 29 | return ct; 30 | } 31 | 32 | var fieldInfo = typeof(ControlType).GetField(value, 33 | BindingFlags.GetField | BindingFlags.Public | 34 | BindingFlags.Static | BindingFlags.Instance | 35 | BindingFlags.IgnoreCase); 36 | 37 | if (fieldInfo == null) 38 | { 39 | throw new InvalidSelectorException(value + " is not supported control type"); 40 | } 41 | 42 | ct = (ControlType)fieldInfo.GetValue(null); 43 | _controlTypeCache.Add(value, ct); 44 | return ct; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WinAppDriver/Extensions/TreeWalkerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Automation; 4 | 5 | namespace WinAppDriver.Extensions 6 | { 7 | public static class TreeWalkerExtensions 8 | { 9 | public static AutomationElement GetFirstChild(this TreeWalker treeWalker, AutomationElement element, System.Threading.CancellationToken cancellationToken, int numberOfRetries = 10) 10 | { 11 | Exception e = null; 12 | while (numberOfRetries-- >= 0) 13 | { 14 | if (cancellationToken.IsCancellationRequested) 15 | { 16 | return null; 17 | } 18 | 19 | try 20 | { 21 | return treeWalker.GetFirstChild(element); 22 | } 23 | catch (COMException comEx) 24 | { 25 | e = comEx; 26 | // when application is busy, following exception is thrown 27 | // System.Runtime.InteropServices.COMException (0x80131505): Operation timed out. (Exception from HRESULT: 0x80131505) 28 | // this method will wait try to wait for the application to be accessible via UIA again 29 | if (comEx.IsTimeout()) 30 | { 31 | System.Threading.Thread.Sleep(250); 32 | continue; 33 | } 34 | 35 | throw; 36 | } 37 | } 38 | 39 | throw e; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /WinAppDriver/Host.cs: -------------------------------------------------------------------------------- 1 | using Nancy.Hosting.Self; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace WinAppDriver.Server 8 | { 9 | public class Host : IDisposable 10 | { 11 | private readonly NancyHost _nancyHost; 12 | 13 | public Host(Uri uri) 14 | { 15 | var hostConfigs = new HostConfiguration 16 | { 17 | UrlReservations = new UrlReservations() { CreateAutomatically = true } 18 | }; 19 | 20 | _nancyHost = new NancyHost(new Bootstrapper(), hostConfigs, uri); 21 | } 22 | 23 | public void Start() 24 | { 25 | _nancyHost.Start(); 26 | } 27 | 28 | public void Dispose() 29 | { 30 | _nancyHost.Dispose(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /WinAppDriver/Infrastructure/CacheStore.cs: -------------------------------------------------------------------------------- 1 | using WinAppDriver.Server; 2 | using System; 3 | using System.Collections.Concurrent; 4 | 5 | namespace WinAppDriver.Infrastructure 6 | { 7 | public class CacheStore 8 | { 9 | private static Lazy> _cacheStore = 10 | new Lazy>( 11 | () => new ConcurrentDictionary(), 12 | true); 13 | 14 | private static Lazy> _commandtore = 15 | new Lazy>( 16 | () => new ConcurrentDictionary(), 17 | true); 18 | 19 | public static ConcurrentDictionary Store => _cacheStore.Value; 20 | 21 | public static ConcurrentDictionary CommandStore => _commandtore.Value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /WinAppDriver/Infrastructure/ElementCacheFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Automation; 3 | 4 | namespace WinAppDriver.Infrastructure 5 | { 6 | public class ElementCacheFactory 7 | { 8 | public static ElementCache Get(string sessionId) 9 | { 10 | var hwnd = new IntPtr(int.Parse(sessionId)); 11 | return new ElementCache(hwnd, AutomationElement.FromHandle(hwnd)); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WinAppDriver/Infrastructure/ElementFinders/ActiveElementFinder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using System.Windows.Automation; 4 | 5 | namespace WinAppDriver.Infrastructure.ElementFinders 6 | { 7 | public class ActiveElementFinder : IElementFinder 8 | { 9 | public IEnumerable Find(AutomationElement automationElement, CancellationToken cancellationToken) 10 | { 11 | yield return AutomationElement.FocusedElement; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WinAppDriver/Infrastructure/ElementFinders/WindowElementFinder.cs: -------------------------------------------------------------------------------- 1 | using CodePlex.XPathParser; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Windows.Automation; 7 | using WinAppDriver.XPath; 8 | 9 | namespace WinAppDriver.Infrastructure.ElementFinders 10 | { 11 | public class WindowElementFinder : IElementFinder 12 | { 13 | private readonly AutomationElement _rootElement; 14 | private readonly string _criteria; 15 | 16 | public WindowElementFinder(string criteria, AutomationElement rootElement) 17 | { 18 | _criteria = criteria.Replace("//Window", "self::node()"); 19 | _rootElement = rootElement; 20 | } 21 | 22 | public IEnumerable Find(AutomationElement automationElement, CancellationToken cancellationToken) 23 | { 24 | var walker = new AutomationElementTreeWalker(new XPathParser().Parse(_criteria, new WalkerBuilder())); 25 | return new BreadthFirstSearch() 26 | .Find(_rootElement, ControlType.Window, cancellationToken) 27 | .Where(w => w.Current.ControlType == ControlType.Window) 28 | .SelectMany(window => walker.Find(window, cancellationToken)); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /WinAppDriver/Input/Devices/Keyboard.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Collections.Generic; 3 | using System.Windows.Automation; 4 | using WinAppDriver.Server; 5 | 6 | namespace WinAppDriver.Input.Devices 7 | { 8 | public class Keyboard 9 | { 10 | private JArray _array; 11 | private List _keysHeld; 12 | 13 | public Keyboard(JArray array) 14 | { 15 | _array = array; 16 | _keysHeld = new List(); 17 | } 18 | 19 | public void Execute(CommandEnvironment commandEnvironment, System.Threading.CancellationToken cancellationToken) 20 | { 21 | AutomationElement.FromHandle(commandEnvironment.WindowHandle).SetFocus(); 22 | 23 | var actions = GetActions(); 24 | var strategy = new Strategies.SendKeys.OneByOne(); 25 | strategy.Execute(commandEnvironment, new Dictionary { { "actions", actions } }, cancellationToken); 26 | } 27 | 28 | private IEnumerable GetActions() 29 | { 30 | foreach (var t in _array) 31 | { 32 | var keyCode = t.Value(); 33 | var tmp = ProcessKey(keyCode); 34 | foreach (var tm in tmp) 35 | { 36 | yield return tm; 37 | } 38 | } 39 | 40 | foreach (var heldKey in _keysHeld) 41 | { 42 | yield return new JObject 43 | { 44 | ["type"] = "keyUp", 45 | ["value"] = heldKey 46 | }; 47 | } 48 | 49 | yield break; 50 | } 51 | 52 | private JObject[] ProcessKey(string keyCode) 53 | { 54 | if (/*!KeyboardActions.TryGetKey(keyCode[0], out var key) || */!KeyboardActions.IsSpecial(keyCode)) 55 | { 56 | return new[] { 57 | new JObject 58 | { 59 | ["type"] = "keyDown", 60 | ["value"] = keyCode 61 | }, 62 | new JObject 63 | { 64 | ["type"] = "keyUp", 65 | ["value"] = keyCode 66 | } 67 | }; 68 | } 69 | 70 | if (_keysHeld.Contains(keyCode)) 71 | { 72 | _keysHeld.Remove(keyCode); 73 | return new[] { 74 | new JObject 75 | { 76 | ["type"] = "keyUp", 77 | ["value"] = keyCode 78 | } 79 | }; 80 | } 81 | 82 | _keysHeld.Add(keyCode); 83 | 84 | return new[] { 85 | new JObject 86 | { 87 | ["type"] = "keyDown", 88 | ["value"] = keyCode 89 | } 90 | }; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /WinAppDriver/Input/InputDeviceException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WinAppDriver.Input 8 | { 9 | public class InputDeviceException : Exception 10 | { 11 | public InputDeviceException(string message) : base(message) { } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /WinAppDriver/Input/MouseButton.cs: -------------------------------------------------------------------------------- 1 | // (c) Copyright Microsoft Corporation. 2 | // This source is subject to the Microsoft Public License (Ms-PL). 3 | // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. 4 | // All other rights reserved. 5 | 6 | namespace Microsoft.Test.Input 7 | { 8 | /// 9 | /// Defines values that specify the buttons on a mouse device. 10 | /// 11 | public enum MouseButton 12 | { 13 | /// 14 | /// The left mouse button. 15 | /// 16 | Left = 0, 17 | 18 | /// 19 | /// The middle mouse button. 20 | /// 21 | Middle = 1, 22 | 23 | /// 24 | /// The right mouse button. 25 | /// 26 | Right = 2, 27 | 28 | /// 29 | /// The first extended mouse button. 30 | /// 31 | XButton1 = 3, 32 | 33 | /// 34 | /// The second extended mouse button 35 | /// 36 | XButton2 = 4, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WinAppDriver/Input/MouseButtonState.cs: -------------------------------------------------------------------------------- 1 | // (c) Copyright Microsoft Corporation. 2 | // This source is subject to the Microsoft Public License (Ms-PL). 3 | // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. 4 | // All other rights reserved. 5 | 6 | namespace Microsoft.Test.Input 7 | { 8 | /// 9 | /// The state of the mouse button. 10 | /// 11 | internal enum MouseButtonState 12 | { 13 | Released = 0, 14 | Pressed = 1, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WinAppDriver/Input/NamespaceDoc.cs: -------------------------------------------------------------------------------- 1 | // (c) Copyright Microsoft Corporation. 2 | // This source is subject to the Microsoft Public License (Ms-PL). 3 | // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. 4 | // All other rights reserved. 5 | 6 | namespace Microsoft.Test.Input 7 | { 8 | /// 9 | /// Contains facilities for realistic simulation of user input 10 | /// (keyboard, mouse, pen, multi-touch). 11 | /// 12 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812")] 13 | [System.Runtime.CompilerServices.CompilerGenerated()] 14 | class NamespaceDoc 15 | { 16 | // Empty class used only for generation of namespace comments. 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WinAppDriver/Input/SendMouseInputFlags.cs: -------------------------------------------------------------------------------- 1 | // (c) Copyright Microsoft Corporation. 2 | // This source is subject to the Microsoft Public License (Ms-PL). 3 | // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details. 4 | // All other rights reserved. 5 | 6 | using System; 7 | 8 | namespace Microsoft.Test.Input 9 | { 10 | /// 11 | /// Mouse input flags used by the Native Input struct. 12 | /// 13 | [Flags] 14 | internal enum SendMouseInputFlags 15 | { 16 | Move = 0x0001, 17 | LeftDown = 0x0002, 18 | LeftUp = 0x0004, 19 | RightDown = 0x0008, 20 | RightUp = 0x0010, 21 | MiddleDown = 0x0020, 22 | MiddleUp = 0x0040, 23 | XDown = 0x0080, 24 | XUp = 0x0100, 25 | Wheel = 0x0800, 26 | Absolute = 0x8000, 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /WinAppDriver/JsonNetSerializer.cs: -------------------------------------------------------------------------------- 1 | using Nancy; 2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | 7 | namespace WinAppDriver.Server 8 | { 9 | public class JsonNetSerializer : ISerializer 10 | { 11 | private readonly JsonSerializer _serializer; 12 | 13 | public JsonNetSerializer() 14 | { 15 | var settings = new JsonSerializerSettings 16 | { 17 | //ContractResolver = new CamelCasePropertyNamesContractResolver() 18 | }; 19 | 20 | _serializer = JsonSerializer.Create(settings); 21 | } 22 | 23 | IEnumerable ISerializer.Extensions => throw new NotImplementedException(); 24 | 25 | bool ISerializer.CanSerialize(string contentType) 26 | { 27 | return contentType == "application/json"; 28 | } 29 | 30 | void ISerializer.Serialize(string contentType, TModel model, Stream outputStream) 31 | { 32 | using (var writer = new JsonTextWriter(new StreamWriter(outputStream))) 33 | { 34 | _serializer.Serialize(writer, model); 35 | writer.Flush(); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /WinAppDriver/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | WindowsPhoneDriverBrowser 12 | Jim Evans 13 | Assets\StoreLogo.png 14 | 15 | 16 | 17 | 6.3.1 18 | 6.3.1 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | AgHostSvcs.dll 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /WinAppDriver/PngWriter/WritableBitmapExtensions.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright 2014 Salesforce.com 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | using System; 19 | using System.Collections.Generic; 20 | using System.IO; 21 | using System.Linq; 22 | using System.Text; 23 | using System.Threading.Tasks; 24 | using System.Windows.Media.Imaging; 25 | 26 | namespace WindowsPhoneDriverBrowser 27 | { 28 | /// 29 | /// Contains extension methods for the class. 30 | /// 31 | public static class WritableBitmapExtensions 32 | { 33 | /// 34 | /// Saves a to a stream as a PNG file. 35 | /// 36 | /// The to save. 37 | /// The to which to save the PNG-encoded bits. 38 | public static void SavePng(this WriteableBitmap bitmap, Stream stream) 39 | { 40 | ToolStackPNGWriterLib.PNGWriter.WritePNG(bitmap, stream); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /WinAppDriver/Properties/AppManifest.xml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /WinAppDriver/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WinAppDriver")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WinAppDriver")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("99665496-5da2-4f6b-813b-bec10187cefd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | 38 | [assembly: Nancy.IncludeInNancyAssemblyScanning] -------------------------------------------------------------------------------- /WinAppDriver/Properties/WMAppManifest.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Assets\ApplicationIcon.png 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Assets\Tiles\FlipCycleTileSmall.png 20 | 0 21 | Assets\Tiles\FlipCycleTileMedium.png 22 | WindowsPhoneDriverBrowser 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /WinAppDriver/Strategies/SendKeys/Grouped.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using WinAppDriver.Server; 5 | 6 | namespace WinAppDriver.Strategies.SendKeys 7 | { 8 | public class Grouped : ISendKeyStrategy 9 | { 10 | public Response Execute(CommandEnvironment commandEnvironment, Dictionary parameters, CancellationToken cancellationToken) 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /WinAppDriver/Strategies/SendKeys/ISendKeysStrategy.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Collections.Generic; 3 | using WinAppDriver.Server; 4 | 5 | namespace WinAppDriver.Strategies.SendKeys 6 | { 7 | public enum SendKeyStrategyType 8 | { 9 | OneByOne, 10 | Grouped, 11 | SetValue 12 | } 13 | 14 | public interface ISendKeyStrategy 15 | { 16 | Response Execute(CommandEnvironment environment, Dictionary parameters, System.Threading.CancellationToken cancellationToken); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /WinAppDriver/Strategies/SendKeys/OneByOne.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using WinAppDriver.Input; 5 | using WinAppDriver.Server; 6 | 7 | namespace WinAppDriver.Strategies.SendKeys 8 | { 9 | public class OneByOne : ISendKeyStrategy 10 | { 11 | public Response Execute(CommandEnvironment commandEnvironment, Dictionary parameters, CancellationToken cancellationToken) 12 | { 13 | if (!parameters.TryGetValue("actions", out object o)) 14 | { 15 | return Response.CreateMissingParametersResponse("actions"); 16 | } 17 | 18 | var actions = (JArray)o; 19 | 20 | foreach (var block in actions) 21 | { 22 | var blockActions = (JArray)block["actions"]; 23 | var type = block["type"].Value(); 24 | 25 | switch (type) 26 | { 27 | case "pointer": 28 | new MouseActions(blockActions, commandEnvironment).Execute(); 29 | break; 30 | case "key": 31 | new KeyboardActions(blockActions).Execute(); 32 | break; 33 | } 34 | } 35 | 36 | return Response.CreateSuccessResponse(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /WinAppDriver/Strategies/SendKeys/SetValue.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using WinAppDriver.Extensions; 4 | using WinAppDriver.Server; 5 | 6 | namespace WinAppDriver.Strategies.SendKeys 7 | { 8 | public class SetValue : ISendKeyStrategy 9 | { 10 | private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); 11 | 12 | public Response Execute(CommandEnvironment commandEnvironment, Dictionary parameters, CancellationToken cancellationToken) 13 | { 14 | if (!parameters.TryGetValue("text", out var text)) 15 | { 16 | return Response.CreateMissingParametersResponse("text"); 17 | } 18 | 19 | var id = parameters["ID"]; 20 | var automationElement = commandEnvironment.Cache.GetElement(id); 21 | automationElement.SetText(text?.ToString() ?? ""); 22 | 23 | Logger.Info($"Text {text} set to element {id}."); 24 | 25 | return Response.CreateSuccessResponse(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /WinAppDriver/TextEventArgs.cs: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // Copyright (c) 2014 Salesforce.com, Inc. 4 | // All rights reserved. 5 | // 6 | // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 7 | // following conditions are met: 8 | // 9 | // Redistributions of source code must retain the above copyright notice, this list of conditions and the following 10 | // disclaimer. 11 | // 12 | // Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 13 | // following disclaimer in the documentation and/or other materials provided with the distribution. 14 | // 15 | // Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products 16 | // derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 19 | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 24 | // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | // 26 | 27 | using System; 28 | using System.Collections.Generic; 29 | using System.Linq; 30 | using System.Text; 31 | using System.Threading.Tasks; 32 | 33 | namespace WinAppDriver.Server 34 | { 35 | /// 36 | /// Arguments sent when a text event is raised. 37 | /// 38 | public class TextEventArgs : EventArgs 39 | { 40 | private string text = string.Empty; 41 | 42 | /// 43 | /// Initializes a new instance of the class. 44 | /// 45 | /// The text raised with the event. 46 | public TextEventArgs(string text) 47 | { 48 | this.text = text; 49 | } 50 | 51 | /// 52 | /// Gets the text of the event. 53 | /// 54 | public string Text 55 | { 56 | get { return this.text; } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /WinAppDriver/Utils/PointComparer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows; 3 | 4 | namespace WinAppDriver.Utils 5 | { 6 | public class PointComparer : IComparer 7 | { 8 | public int Compare(Point a, Point b) 9 | { 10 | if (a.Y < b.Y) 11 | { 12 | return -1; 13 | } 14 | 15 | if (a.Y > b.Y) 16 | { 17 | return 1; 18 | } 19 | 20 | if (a.X == b.X) 21 | { 22 | return 0; 23 | } 24 | 25 | return a.X < b.X ? -1 : 1; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /WinAppDriver/XPath/Functions/Contains.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Automation; 4 | 5 | namespace WinAppDriver.XPath.Functions 6 | { 7 | public class Contains : FunctionElementBase, ICondition, IEvaluate 8 | { 9 | private readonly IList _args; 10 | 11 | public Contains(IList args) 12 | { 13 | _args = args; 14 | } 15 | 16 | public object Evaluate(AutomationElement element, Type expectedType) 17 | { 18 | return Matches(element, -1); 19 | } 20 | 21 | public bool Matches(AutomationElement element, int index) 22 | { 23 | if (_args.Count != 2) 24 | { 25 | throw new NotImplementedException($"XPath function 'contains' requires 2 parameters."); 26 | } 27 | 28 | var haystack = (_args[0] as IEvaluate).Evaluate(element, typeof(string)); 29 | var needle = (_args[1] as IEvaluate).Evaluate(element, typeof(string)); 30 | if (haystack is string && needle is string) 31 | { 32 | return haystack.ToString().Contains(needle.ToString()); 33 | } 34 | 35 | throw new NotImplementedException($"Unexpected types of parameters of XPath function 'contains': '{haystack?.GetType().FullName}' and '{needle?.GetType().FullName}'."); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /WinAppDriver/XPath/Functions/FunctionElementBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using System.Windows.Automation; 4 | 5 | namespace WinAppDriver.XPath.Functions 6 | { 7 | public class FunctionElementBase : IXPathExpression 8 | { 9 | IEnumerable IXPathExpression.Find(AutomationElement root, IList collection, CancellationToken cancellationToken) 10 | { 11 | return collection; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /WinAppDriver/XPath/Functions/FunctionFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace WinAppDriver.XPath.Functions 4 | { 5 | public class FunctionElementFactory 6 | { 7 | public static IXPathExpression GetFunctionElement(string prefix, string name, IList args) 8 | { 9 | switch (name) 10 | { 11 | case "contains": 12 | return new Contains(args); 13 | case "starts-with": 14 | return new StartsWith(args); 15 | } 16 | 17 | return new FunctionElement(prefix, name, args); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /WinAppDriver/XPath/Functions/StartsWith.cs: -------------------------------------------------------------------------------- 1 | using OpenQA.Selenium; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Automation; 8 | using WinAppDriver.Extensions; 9 | 10 | namespace WinAppDriver.XPath.Functions 11 | { 12 | public class StartsWith : FunctionElementBase, ICondition 13 | { 14 | private readonly IList _args; 15 | 16 | public StartsWith(IList args) 17 | { 18 | _args = args; 19 | } 20 | 21 | public bool Matches(AutomationElement element, int index) 22 | { 23 | if (_args.Count != 2) 24 | { 25 | throw new InvalidSelectorException("Function starts-with expects 2 parameters."); 26 | } 27 | 28 | var value = (_args[0] as IEvaluate).Evaluate(element, typeof(string)); 29 | var arg = string.Empty; 30 | if (value is AutomationElement automationElement) 31 | { 32 | arg = automationElement.GetText(); 33 | } 34 | 35 | if (value is string) 36 | { 37 | arg = value.ToString(); 38 | } 39 | 40 | var v = (_args[1] as IEvaluate).Evaluate(element, typeof(string)).ToString(); 41 | return arg.StartsWith(v); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /WinAppDriver/XPath/Iterators/IteratorBase.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | 4 | namespace WinAppDriver.XPath.Iterators 5 | { 6 | public class IteratorBase : IEnumerable 7 | { 8 | public virtual IEnumerator GetEnumerator() 9 | { 10 | return new Enumerator(this); 11 | } 12 | 13 | IEnumerator IEnumerable.GetEnumerator() 14 | { 15 | return new Enumerator(this); 16 | } 17 | 18 | public class Enumerator : IEnumerator 19 | { 20 | public T Current => throw new System.NotImplementedException(); 21 | 22 | object IEnumerator.Current => throw new System.NotImplementedException(); 23 | 24 | public Enumerator(IteratorBase iterator) 25 | { 26 | 27 | } 28 | 29 | public bool MoveNext() 30 | { 31 | throw new System.NotImplementedException(); 32 | } 33 | 34 | public void Reset() 35 | { 36 | throw new System.NotImplementedException(); 37 | } 38 | 39 | public void Dispose() 40 | { 41 | throw new System.NotImplementedException(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /WinAppDriver/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /WinAppDriver/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /XPathParser-master/.gitignore: -------------------------------------------------------------------------------- 1 | *.lock.json 2 | .vs/ 3 | bin/ 4 | obj/ -------------------------------------------------------------------------------- /XPathParser-master/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Microsoft Public License (Ms-PL) 2 | 3 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 4 | 5 | 1. Definitions 6 | 7 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. 8 | 9 | A "contribution" is the original software, or any additions or changes to the software. 10 | 11 | A "contributor" is any person that distributes its contribution under this license. 12 | 13 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 14 | 15 | 2. Grant of Rights 16 | 17 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 18 | 19 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 20 | 21 | 3. Conditions and Limitations 22 | 23 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 24 | 25 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 26 | 27 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 28 | 29 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 30 | 31 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. -------------------------------------------------------------------------------- /XPathParser-master/README.md: -------------------------------------------------------------------------------- 1 | # XPathParser: XPath parser in C# source code. 2 | [![Build status](https://ci.appveyor.com/api/projects/status/7lupdjmn2tftttk1?svg=true)](https://ci.appveyor.com/project/qmfrederik/xpathparser) 3 | 4 | Close to one System.Xml uses in the XslCompiledTransform. 5 | Currently supports XPath 1.0 grammar. 6 | 7 | This implementation uses _Builder_ pattern to separate parsing code from result the parser should produce. 8 | 9 | While parsing the source XPath parser calls method in the methods of `IXPathBuilder` interface provided by caller. 10 | 11 | User of this code expected to write his own `IXPathBuilder` implementation. 12 | Source code of this project contains two `IXPathBuilder` implementations for demo/testing purpose: 13 | * `XPathTreeBuilder` - constructs XLinq tree that represents XPath syntax tree. 14 | * `XPathStringBuilder` - compiles syntax tree back to XPaht string. 15 | 16 | ## Installation 17 | 18 | Install using the command line: 19 | 20 | ``` 21 | Install-Package XPathParser 22 | ``` 23 | 24 | ## Architecture 25 | XPath is a language to query data from XML documents. It is built in to XSLT and can be used standalone in several .NET APIs. (http://www.w3.org/TR/xpath) 26 | In some cases customers need to parse XPath expressions themselves to analyze, modify or validate them. 27 | `XPathParser` is the class that can help you doing this. 28 | 29 | To make parser extensible `XPathParser` uses "Builder" pattern. It takes string with XPath expression and instance of `IXPathBuilder` interface (builder) as input and generates set of calls to the builder. 30 | 31 | This way implementation of the `XPathParser` doesn't dictate how parsed expression would be represented. 32 | 33 | With the `XPathParser` we provide `XPathParserTest` that contains two sample implements of the `IXPathBuilder`: `XPathTreeBuilder` which builds XLinq tree as a result of parsing and `XPathStringBuilder` that generates string implementation of the compiled XPath. 34 | 35 | The work of `XPathParser` can be demonstrated in the following diagram: 36 | 37 | ![Architecture](architecture.png) 38 | 39 | ## Examples 40 | 41 | ### Expression "1 + 2": 42 | ``` 43 | ctx = StartBuild(); 44 | return EndBuild(Operator(XPathOperator.Plus, Number(1), Number(2))) 45 | ``` 46 | 47 | ### Expression "a/@*": 48 | 49 | ``` 50 | ctx = StartBuild(); 51 | stp1 = Axis(ctx, XPathAxis.Child, QilXmlNodeKind.Element, "", "a"); 52 | stp2 = Axis(stp1, XPathAxis.Attribute, QilXmlNodeKind.Attribute, "", ""); 53 | return EndBuild(JoinStep(stp1, stp2)); 54 | ``` 55 | 56 | ### Expression "parent:a[@b]": 57 | 58 | ctx = StartBuild(); 59 | stp1 = Axis(ctx, XPathAxis.Parent, QilXmlNodeKind.Element, "", "a"); 60 | stp2 = Axis(stp1, XPathAxis.Attribute, QilXmlNodeKind.Attribute, "", "b"); 61 | return EndBuild(Predicate(stp1, stp2)); 62 | 63 | ## Credits 64 | This repository was forked from http://xpathparser.codeplex.com/ -------------------------------------------------------------------------------- /XPathParser-master/XPathParser.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | XPathParser 5 | $version$ 6 | Sergey Dubinets 7 | Quamotion 8 | .NET XPath Parser 9 | XPath parser in C# source code. 10 | https://github.com/quamotion/XPathParser 11 | https://github.com/quamotion/XPathParser/blob/master/LICENSE.txt 12 | XPath 13 | en-US 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XPathParser", "XPathParser\XPathParser.csproj", "{A8072758-E8D2-4551-89C2-564BDE162403}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XPathParserTest", "XPathParserTest\XPathParserTest.csproj", "{6706ED44-C0D9-45A0-A911-80B13866E4E2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {A8072758-E8D2-4551-89C2-564BDE162403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {A8072758-E8D2-4551-89C2-564BDE162403}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {A8072758-E8D2-4551-89C2-564BDE162403}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {A8072758-E8D2-4551-89C2-564BDE162403}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {6706ED44-C0D9-45A0-A911-80B13866E4E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {6706ED44-C0D9-45A0-A911-80B13866E4E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {6706ED44-C0D9-45A0-A911-80B13866E4E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {6706ED44-C0D9-45A0-A911-80B13866E4E2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/IXpathBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.XPath; 4 | 5 | namespace CodePlex.XPathParser { 6 | public interface IXPathBuilder { 7 | // Should be called once per build 8 | void StartBuild(); 9 | 10 | // Should be called after build for result tree post-processing 11 | Node EndBuild(Node result); 12 | 13 | Node String(string value); 14 | 15 | Node Number(string value); 16 | 17 | Node Operator(XPathOperator op, Node left, Node right); 18 | 19 | Node Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name); 20 | 21 | Node JoinStep(Node left, Node right); 22 | 23 | // http://www.w3.org/TR/xquery-semantics/#id-axis-steps 24 | // reverseStep is how parser comunicates to builder diference between "ansestor[1]" and "(ansestor)[1]" 25 | Node Predicate(Node node, Node condition, bool reverseStep); 26 | 27 | Node Variable(string prefix, string name); 28 | 29 | Node Function(string prefix, string name, IList args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("XPathParser")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("XPathParser.Properties")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | #if !NETSTANDARD1_3 24 | [assembly: Guid("9c8dde5f-17d6-4a6e-8ee1-27e96b36e244")] 25 | #endif 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/XPathAxis.cs: -------------------------------------------------------------------------------- 1 | namespace CodePlex.XPathParser { 2 | public enum XPathAxis { 3 | Unknown = 0, 4 | Ancestor , 5 | AncestorOrSelf , 6 | Attribute , 7 | Child , 8 | Descendant , 9 | DescendantOrSelf, 10 | Following , 11 | FollowingSibling, 12 | Namespace , 13 | Parent , 14 | Preceding , 15 | PrecedingSibling, 16 | Self , 17 | Root , 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/XPathOperator.cs: -------------------------------------------------------------------------------- 1 | namespace CodePlex.XPathParser { 2 | public enum XPathOperator { 3 | Unknown = 0, 4 | Or, 5 | And, 6 | Eq, 7 | Ne, 8 | Lt, 9 | Le, 10 | Gt, 11 | Ge, 12 | Plus, 13 | Minus, 14 | Multiply, 15 | Divide, 16 | Modulo, 17 | UnaryMinus, 18 | Union 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/XPathParser.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {A8072758-E8D2-4551-89C2-564BDE162403} 9 | Library 10 | Properties 11 | XPathParser 12 | XPathParser 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | XPathParser.snk 40 | true 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/XPathParser.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/XPathParser-master/XPathParser/XPathParser.snk -------------------------------------------------------------------------------- /XPathParser-master/XPathParser/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.1.0-*", 3 | 4 | "authors": [ "Sergey Dubinets" ], 5 | "title": ".NET XPath Parser", 6 | "description": "XPath parser in C# source code.", 7 | 8 | "packOptions": { 9 | "licenseUrl": "https://github.com/quamotion/XPathParser/blob/master/LICENSE.txt", 10 | "owners": [ "quamotion" ], 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/quamotion/XPathParser" 14 | }, 15 | }, 16 | 17 | "dependencies": { 18 | }, 19 | 20 | "buildOptions": { 21 | "keyFile": "XPathParser.snk", 22 | "strongName": true 23 | }, 24 | 25 | "frameworks": { 26 | "netstandard1.3": { 27 | "imports": "dnxcore50", 28 | "dependencies": { 29 | "System.Xml.XPath": "4.0.1", 30 | "System.Collections": "4.0.11", 31 | "System.Text.RegularExpressions": "4.1.0", 32 | "System.Diagnostics.Debug": "4.0.11", 33 | "System.Globalization": "4.0.11", 34 | "System.Runtime.Extensions": "4.1.0" 35 | } 36 | }, 37 | "net20": { 38 | "frameworkAssemblies": { 39 | "System.Xml": "2.0.0.0" 40 | } 41 | }, 42 | "net30": { 43 | "frameworkAssemblies": { 44 | "System.Xml": "2.0.0.0" 45 | } 46 | }, 47 | "net40": { 48 | "frameworkAssemblies": { 49 | "System.Xml": "4.0.0.0" 50 | } 51 | }, 52 | "net45": { 53 | "frameworkAssemblies": { 54 | "System.Xml": "4.0.0.0" 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /XPathParser-master/XPathParserTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("XPathParserTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("MSIT")] 12 | [assembly: AssemblyProduct("XPathParserTest")] 13 | [assembly: AssemblyCopyright("Copyright © MSIT 2008")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("be0e42cb-6663-4b7f-9539-1e9d220818bf")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParserTest/XPathParserTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {6706ED44-C0D9-45A0-A911-80B13866E4E2} 9 | Exe 10 | Properties 11 | XPathParserTest 12 | XPath_to_String 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | 30 | 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | 38 | 39 | 40 | 41 | 42 | 3.5 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {A8072758-E8D2-4551-89C2-564BDE162403} 55 | XPathParser 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /XPathParser-master/XPathParserTest/XPathTreeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Xml.Linq; 3 | using CodePlex.XPathParser; 4 | 5 | namespace XPathParserTest 6 | { 7 | class XPathTreeBuilder : IXPathBuilder 8 | { 9 | public void StartBuild() { } 10 | 11 | public XElement EndBuild(XElement result) 12 | { 13 | return result; 14 | } 15 | 16 | public XElement String(string value) 17 | { 18 | return new XElement("string", new XAttribute("value", value)); 19 | } 20 | 21 | public XElement Number(string value) 22 | { 23 | return new XElement("number", new XAttribute("value", value)); 24 | } 25 | 26 | public XElement Operator(XPathOperator op, XElement left, XElement right) 27 | { 28 | if (op == XPathOperator.UnaryMinus) 29 | { 30 | return new XElement("negate", left); 31 | } 32 | return new XElement(op.ToString(), left, right); 33 | } 34 | 35 | public XElement Axis(XPathAxis xpathAxis, System.Xml.XPath.XPathNodeType nodeType, string prefix, string name) 36 | { 37 | return new XElement(xpathAxis.ToString(), 38 | new XAttribute("nodeType", nodeType.ToString()), 39 | new XAttribute("prefix", prefix ?? "(null)"), 40 | new XAttribute("name", name ?? "(null)") 41 | ); 42 | } 43 | 44 | public XElement JoinStep(XElement left, XElement right) 45 | { 46 | return new XElement("step", left, right); 47 | } 48 | 49 | public XElement Predicate(XElement node, XElement condition, bool reverseStep) 50 | { 51 | return new XElement("predicate", new XAttribute("reverse", reverseStep), node, condition); 52 | } 53 | 54 | public XElement Variable(string prefix, string name) 55 | { 56 | return new XElement("variable", 57 | new XAttribute("prefix", prefix ?? "(null)"), 58 | new XAttribute("name", name ?? "(null)") 59 | ); 60 | } 61 | 62 | public XElement Function(string prefix, string name, IList args) 63 | { 64 | XElement xe = new XElement("variable", 65 | new XAttribute("prefix", prefix ?? "(null)"), 66 | new XAttribute("name", name ?? "(null)") 67 | ); 68 | foreach (XElement e in args) 69 | { 70 | xe.Add(e); 71 | } 72 | return xe; 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /XPathParser-master/appveyor.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - choco install -y wget 3 | - wget -q https://download.microsoft.com/download/4/6/1/46116DFF-29F9-4FF8-94BF-F9BE05BE263B/packages/DotNetCore.1.0.0.RC2-SDK.Preview1-x64.exe 4 | - DotNetCore.1.0.0.RC2-SDK.Preview1-x64.exe /install /quiet /log dotnetinstall.log 5 | - ps: Push-AppveyorArtifact "dotnetinstall.log" 6 | 7 | build_script: 8 | - cmd: cd XPathParser 9 | - cmd: dotnet restore 10 | - cmd: dotnet build -c Release --version-suffix r%APPVEYOR_BUILD_NUMBER% 11 | - cmd: dotnet pack -c Release --version-suffix r%APPVEYOR_BUILD_NUMBER% 12 | 13 | on_success: 14 | - ps: Push-AppveyorArtifact "bin\Release\XPathParser.1.1.0-r$($env:APPVEYOR_BUILD_NUMBER).nupkg" 15 | - ps: Push-AppveyorArtifact "bin\Release\XPathParser.1.1.0-r$($env:APPVEYOR_BUILD_NUMBER).symbols.nupkg" -------------------------------------------------------------------------------- /XPathParser-master/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/XPathParser-master/architecture.png -------------------------------------------------------------------------------- /libs/Interop.UIAutomationClient.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/libs/Interop.UIAutomationClient.dll -------------------------------------------------------------------------------- /libs/ManagedWinapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/libs/ManagedWinapi.dll -------------------------------------------------------------------------------- /libs/ManagedWinapiNativeHelper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/libs/ManagedWinapiNativeHelper.dll -------------------------------------------------------------------------------- /libs/UIAComWrapper.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kfrajtak/WinAppDriver/cc6b882d0584e0ad669841fc08706bfb6dbfe1db/libs/UIAComWrapper.dll --------------------------------------------------------------------------------