WinAppDriver icon indicating copy to clipboard operation
WinAppDriver copied to clipboard

Appium Dotnet 5.0.0-beta01: Cannot instantiate WIndowsDriver: AppiumOptions "Vendor Prefix" causing driver instantiation error

Open pradeipp opened this issue 2 years ago • 23 comments

I was trying out the Appium 5.0.0 Beta01. My capabilities/options looked like this:

            var options = new AppiumOptions();
            options.AddAdditionalCapability("app", "root");
            options.AddAdditionalCapability("ms:experimental-webdriver", true);

            WindowsDriver driver = new WindowsDriver(new Uri(WinAppDriverUrl), options, TimeSpan.FromSeconds(60));

but this set of options, specifically the option for ("app", "root), threw this error: There is already an option for the appium:app capability. Please use the Application property instead. Parameter name: capabilityName

so I replaced it with this property instead: options.App = "root"; which apparently passes the capability as ("appiumoption:app","root") instead of the old ("app", "root") key-value pair. and so now I get this errorr: OpenQA.Selenium.WebDriverArgumentException: Bad capabilities. Specify either app or appTopLevelWindow to create a session

I looked into the Appium dotnet source code and looks like the AppiumOptions class's method to create a new AppiumOption has been modified: AppiumOptions.cs diff: Appium 4.3.1 vs 5.0.0 Beta01 This method in particular seems to have brought the change, adding a vendor prefix before any and all additional options/capabilities:

public void AddAdditionalAppiumOption(string optionName, object optionValue)
        {
            string name = optionName.Contains(":") ? optionName : $"{VendorPrefix}:{optionName}";
            this.ValidateCapabilityName(name);
            this.additionalAppiumOptions[name] = optionValue;
        }

I couldn't find any way to get around it. Here's a ticket for this issue in the Appium Dotnet Repo: https://github.com/appium/appium-dotnet-driver/issues/487

@kat-y @DHowett Is this being taken care of for the next release? This is a blocker on the upgrade path to Selenium 4 and Appium 5.

pradeipp avatar Mar 08 '22 12:03 pradeipp

This works

 var desktopCapabilities = new AppiumOptions();
            desktopCapabilities.App =  "Root";
            string WindowsApplicationDriverUrl = "http://127.0.0.1:4725/wd/hub";
            desktopSession = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), desktopCapabilities);
            Assert.IsNotNull(desktopSession);

            var RSWindow = desktopSession.FindElementByName("");
            var RSTopLevelWindowHandle = RSWindow.GetAttribute("NativeWindowHandle");
            RSTopLevelWindowHandle = (int.Parse(RSTopLevelWindowHandle)).ToString("x");

            var appcapabilities = new AppiumOptions();
            appcapabilities.AddAdditionalAppiumOption("appTopLevelWindow", RSTopLevelWindowHandle);
            appcapabilities.AddAdditionalAppiumOption("newCommandTimeout", 300);
            driver = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appcapabilities, TimeSpan.FromSeconds(50));

anunay1 avatar Mar 08 '22 13:03 anunay1

Hi @anunay1 thanks for the help but if you see my post, I mention using the dektopCapabilities.App = "Root" and still getting that error. So your code doesn't work either. What's your Appium Nuget package version?

pradeipp avatar Mar 08 '22 16:03 pradeipp

The same that you are using, can you share the code

anunay1 avatar Mar 09 '22 10:03 anunay1

The "WindowsElement" class is deprecated in Appium 5 beta image

How were you able to run this line of code? with the WindowsDriver<WindowsElement>? Can you double check that your Nuget Appium package version is not 4.3.1?

desktopSession = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), desktopCapabilities);

I've posted my code in the original post, that's pretty much it, I'm trying to grab hold of the 'root' app in the desktop

pradeipp avatar Mar 09 '22 11:03 pradeipp

oh my bad I am using 5.0.0-alpha appium version.

anunay1 avatar Mar 09 '22 11:03 anunay1

Hi @anunay1 were you able to make it run with appium 5.0.0-beta01?

pradeipp avatar Mar 14 '22 08:03 pradeipp

No I have not tried.

anunay1 avatar Mar 14 '22 08:03 anunay1

@pradeipp I am able to make it work with the below code with notepad application with appium 5.0.0-beta01

using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;
using System;
using System.Diagnostics;
using System.Threading;
using OpenQA.Selenium.Appium.ImageComparison;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium;

namespace POCAppium5beta
{
    [TestClass]
    public class UnitTest1
    {
        private WindowsDriver desktopSession;
        private WindowsDriver driver;
        private WindowsDriver driver1;
        private WindowsDriver desktopSession2;



        [TestMethod]
        public void TestMethod1()
        {
            string mainWindowTitle = "";
            var allProcesses1 = Process.GetProcesses();
            foreach (Process process in allProcesses1)
            {
                if (process.ProcessName.Contains("notepad"))
                {
                    mainWindowTitle = process.MainWindowTitle;


                }
            }

            var desktopCapabilities = new AppiumOptions();
            desktopCapabilities.App = "Root";
            string WindowsApplicationDriverUrl = "http://127.0.0.1:4725/wd/hub";
            desktopSession = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), desktopCapabilities);
            Assert.IsNotNull(desktopSession);

            var RSWindow = desktopSession.FindElement(MobileBy.Name(mainWindowTitle));
            var RSTopLevelWindowHandle = RSWindow.GetAttribute("NativeWindowHandle");
            RSTopLevelWindowHandle = (int.Parse(RSTopLevelWindowHandle)).ToString("x");

            var appcapabilities = new AppiumOptions();
            appcapabilities.AddAdditionalAppiumOption("appTopLevelWindow", RSTopLevelWindowHandle);
            appcapabilities.AddAdditionalAppiumOption("newCommandTimeout", 300);
            driver = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), appcapabilities, TimeSpan.FromSeconds(50));

            driver.FindElement(MobileBy.Name("Text Editor")).SendKeys("Hello there");

anunay1 avatar Mar 14 '22 09:03 anunay1

and if you want to launch the app you can use the below code:

            var desktopCapabilities = new AppiumOptions();
            desktopCapabilities.App = @"Your app";
            string WindowsApplicationDriverUrl = "http://127.0.0.1:4725/wd/hub";
            desktopSession = new WindowsDriver(new Uri(WindowsApplicationDriverUrl), desktopCapabilities);
            Assert.IsNotNull(desktopSession);
            desktopSession.FindElement(MobileBy.Name("your control")).Click();

anunay1 avatar Mar 14 '22 09:03 anunay1

I still get the same error. What version of winappdriver server are you using? @anunay1 I'm using the latest version, the release candidate rather than the stable release maybe that's impacting it?

pradeipp avatar Mar 14 '22 15:03 pradeipp

I am not using winappdriverserver, I am using Appium server, that is evident from the code I shared:

string WindowsApplicationDriverUrl = "http://127.0.0.1:4725/wd/hub";

anunay1 avatar Mar 14 '22 15:03 anunay1

@kat-y This needs to be taken on priority, if not we will be stuck with the older versions of appium.

anunay1 avatar Mar 14 '22 15:03 anunay1

@pradeipp Did you managed to get it working?

anunay1 avatar Mar 15 '22 07:03 anunay1

@anunay1 No I haven't been able to make it work with WAD server. i'm thinking of trying the appium server soon but idk the risks involved in that. Does it work exactly like the WAD server? or are there any limitations I should be aware of ?

pradeipp avatar Mar 15 '22 09:03 pradeipp

No it works exactly like the winappdriverserver. WAD will not work with the latest version of appium client.

anunay1 avatar Mar 15 '22 09:03 anunay1

Hi all, I am stuck as well. My test stopped working previous week on this error:

System.TypeLoadException : Access is denied: 'OpenQA.Selenium.Remote.DesiredCapabilities'.

So I have started to solve it, I have tried perhaps all possibility combinations:

  • Update Appium.WebDriver (Nuget package in C# project) from 4.3.1 to 5.0b
    • there were described problem above ("Bad capabilities. Specify either app or appTopLevelWindow to create a session")
  • Downgrade Appium.WebDriver into lower version (e.g. 4.0) with Selenium 3.141
    • there were problem, that Appium still uses 4.x Selenium version, probably due to another project in Solution, which uses higher Selenium
  • Link Appium.WebDriver as a standalone project into Solution without Nuget
    • the same problem, higher Selenium has been used
  • Remove Nuget of Appium.WebDriver and starting own Appium server as described above (http://127.0.0.1:4725/wd/hub)
    • problem with starting of application and WinAppDriver has been solved
    • but there were new problem, Finding elements stop working and new one (MobileBy.Name) works only for Notepad example, but not for my application

cernyjan avatar Mar 18 '22 12:03 cernyjan

@cernyjan I had the same. So, I set Selenium packages to the default version of 3.141 in common library and overridden them for another project. With this trick it works

yevheniia-alikberova avatar Apr 02 '22 20:04 yevheniia-alikberova

@yevheniia-alikberova In the end this solution does not fit to us. We have to use higher version of Selenium in other projects due to found vulnerability in that by audit.

cernyjan avatar Apr 21 '22 07:04 cernyjan

On the bright side we got an update from the Dev of this project @DHowett -

https://github.com/microsoft/WinAppDriver/issues/1704#issuecomment-1105500720

Looks like there's a prototype for W3C-style WinAppDriver server in progress and the next release(or the one after that) will hopefully resolve this issue. Fingers crossed.

pradeipp avatar Apr 26 '22 09:04 pradeipp

Morning, not sure if this requires a separate ticket but based on the new AddAdditionalAppiumOption method we're having issues authenticating with BrowserStack for out mobile testing. The new method creates a json which looks like the below: { "appium:PlatformName": "Android", "appium:DeviceName": "Samsung Galaxy S20", "appium:PlatformVersion": "10.0", "appium:BrowserName": "Chrome", "appium:AutomationName": "UiAutomator2", "appium:browserstack.user": "username", "appium:browserstack.key": "password" }

And that throws an authentication error when creating the driver because it appears BrowserStack doesn't recognize the properties any more. With the previous AddAdditionalCapability method the json object was created like this: { "platformName": "Android", "deviceName": "Samsung Galaxy S20", "platformVersion": "10.0", "browserName": "Chrome", "automationName": "UiAutomator2", "browserstack.user": "username", "browserstack.key": "password" }

Any ideas how to pass those properties as before with the new method?

bgoggan avatar May 02 '22 12:05 bgoggan

In case this helps anyone.

Nuget dependency of Appium.WebDriver 5.0.0-beta01 and appium installed ( npm install -g appium )

using NUnit.Framework;
using OpenQA.Selenium.Appium.Windows;
using System;
using System.Diagnostics;
using System.Linq;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium;

namespace TestProject
{
    public class Example: AppiumWindowsDriverTestsBase
    {
        [Test]
        public void Usage()
        {
            var driver = Appium.CreateWindowsDriverFromMainWindowTitle("Your_Main_Window_Title");
            var found = driver.FindElement(ByWindowsAutomation.AccessibilityId("textAutomationId"));
        }
    }

    public abstract class AppiumWindowsDriverTestsBase
    {
        private Process appiumProcess;

        [SetUp]
        public void Setup()
        {
            Appium.StartWinAppDriver();
            appiumProcess = Appium.Start();
        }

        [TearDown]
        public void TearDown()
        {
            appiumProcess.CloseMainWindow();
        }
    }

    public static class ProcessHandleHelper
    {
        public static AppiumOptions AddTopLevelWindow(this AppiumOptions appiumOptions, string topLevelWindowHandle)
        {
            appiumOptions.AddAdditionalAppiumOption("appTopLevelWindow", topLevelWindowHandle);
            return appiumOptions;
        }

        public static AppiumOptions AddTopLevelWindowFromMainWindowTitle(
            this AppiumOptions appiumOptions, 
            string mainWindowTitle
        ) => appiumOptions.AddTopLevelWindow(FindProcessHandleByMainWindowTitle(mainWindowTitle));

        public static string FindProcessHandleByMainWindowTitle(string mainWindowTitle) =>
            FindProcessBy(process => process.MainWindowTitle == mainWindowTitle);


        public static string FindProcessBy(Func<Process, bool> predicate)
        {
            var matchingProcess = Process.GetProcesses().First(predicate);
            return matchingProcess.MainWindowHandle.ToString("x");
        }
    }

    public class Appium
    {
        public const string Uri = "http://127.0.0.1:4723/wd/hub";
        private const string DefaultX86Path = @"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe";
        public static Process Start() => Process.Start("appium");
        public static void StartWinAppDriver(string path = DefaultX86Path) => Process.Start(path, Uri);
        public static WindowsDriver CreateWindowsDriver(AppiumOptions appiumOptions) => 
            new WindowsDriver(new Uri(Uri), appiumOptions);
        public static WindowsDriver CreateWindowsDriverFromMainWindowTitle(string mainWindowTitle, AppiumOptions appiumOptions = null)
        {
            appiumOptions = appiumOptions ?? new AppiumOptions();
            appiumOptions.AddTopLevelWindowFromMainWindowTitle(mainWindowTitle);
            return Appium.CreateWindowsDriver(appiumOptions);
        }
    }
}

tonyhallett avatar Jun 30 '22 12:06 tonyhallett

@pradeipp , did you get your issue resolved? I am using VS 2022 Pro and new to Appium/WinAppDriver. I am following a tutorial on launching notepad.exe using WinAppDriver. This line of code fails:

image

Can you please help?

sramdas2 avatar Oct 12 '22 22:10 sramdas2