Search code examples
c#specflowwinappdriverappium-desktopazure-devops-hosted-agent

Intermittent WebDriverException when running Winappdriver/appium Automation test in MS Hosted Agent ('windows-2022')


Brief background:

  • Automating a winform application using WInAppDriver/Appium.
  • Using Specflow's BDD to define tests
  • At every start of test the automation test will always check if App is open already, if not, then fire-up/initialised application - See InitializedAppium(string application) in screenshot below.
  • In that InitializedAppium(string application) we create "a new instance of the WindowsDriver class using the specified remote address and Appium options".
  • The line; var newDriver = new WindowsDriver<AppiumWebElement>(new Uri("http://127.0.0.1:4723/"), driverOptions); sometimes it throws that intermittent error, and sometimes it don't (mostly the former).
  • Using WinAppDriver & ChromeDriver to execute test.
  • First of all, when running the test locally, everything works flawlessly (at least opening up the App)
  • Secondly, my intermittent issue happening when I'm running the test using the DevOps MS Hosted Agent machine in our pipeline.

Specific error received:

  • OpenQA.Selenium.WebDriverException: The HTTP request to the remote WebDriver server for URL http://127.0.0.1:4723/session timed out after 60 seconds. ---> System.Net.WebException: The operation has timed out

What lead to the error:

  • Trying to fire-up the application! using the following;

      DebugOutput.Log($"Starting {application}");
    
      var driverOptions = new AppiumOptions();
    
      DebugOutput.Log($"NEW {application}");
    
      driverOptions.AddAdditionalCapability(MobileCapabilityType.App, application);
    
      driverOptions.AddAdditionalCapability(MobileCapabilityType.NewCommandTimeout, 500);
    
      driverOptions.AddAdditionalCapability("appium:createSessionTimeout", "20000");
    
      //you may shorten this (<25s) if testing locally, but remember to change it back again)
    
      driverOptions.AddAdditionalCapability("ms:waitForAppLaunch", "50"); 
    
      DebugOutput.Log($"CAPS {application}");
    
      // this is where the failure most times happen when cannot initiate app
    
      var newDriver = new WindowsDriver<AppiumWebElement>(new Uri("http://127.0.0.1:4723/"), driverOptions);
    
      DebugOutput.Log($"Window Driver Succeeded = {newDriver}");
    
      return newDriver; 
    

screenshot legends:

  1. Step into InitializeAppium
  2. The InitializeAppium method
  3. create "a new instance of the WindowsDriver class using the specified remote address and Appium options". This is very much the centre of the question.
  4. debug log when it failed
  5. debug log when it passes
  6. DevOps pipeline between pass and fail with the same exact test (intermittent issue)
  7. The specific error I got when I took out the try and catch statement.

enter image description here

Is there more Additional Capabilities I should add to the AppiumOptions to prevent this timeout...its annoying because it seems that this is the only major issue I am having when running it it in the hosted agent machine!

Any help much appreciated as i'm at the end point where I have no clue what else I can do. If you need need more info to help me, let me know.

Regards,

B


Solution

  • This particular exception is almost impossible to fix. You basically can't fix it, but you can retry it. The only way I've resolved this issue is to try again:

    int maxTries = 5;
    int tries = 1;
    WindowsDriver<AppiumWebElement> newDriver;
    
    do
    {
        try
        {
            newDriver = new WindowsDriver<AppiumWebElement>(...);
        }
        catch (WebException ex)
        {
            newDriver = null;
            DebugOutput.Log($"Failed spawning driver: {ex}");
            // wait 5 seconds for things to calm down
            System.Threading.Thread.Sleep(5000);
        }
        finally
        {
            tries++;
        }
    }
    while (tries < maxTries);
    
    if (newDriver == null)
        throw new InvalidOperationException($"Failed to spawn driver after {maxTries} attempts");
    
    return newDriver;