Search code examples
seleniumuwpappiumcoded-ui-testswinappdriver

How do I wait for an element using the WinAppDriver in UWP?


I'm currently migrating my Coded UI Tests for a UWP app to Appium using the WinAppDriver and I have come across the issue, that I can't wait for an element to show up. There is no way to wait for a element to be "ready" as the Coded UI Test from Microsoft did.

In the ClassInitialize method everything works fine (data is entered on the login view) and the login button is clicked. After the click event is triggered the app shows a progress bar until the user is logged in. My problem is that I cannot wait for the components after the login process.

I have found some code snippets, however, they don't seem to work for me. Here is the extension method I'm currently using:

public static IWebElement WaitForElement(this IWebDriver driver, By by, int timeoutInSeconds)
{
   if (timeoutInSeconds > 0){
      driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(timeoutInSeconds);
      var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
      return wait.Until(ExpectedConditions.ElementIsVisible(by));
   }
   return driver.FindElement(by);
}

I have also read that the implicit timeout for the Windows driver has to be set:

session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);

and overridden in the WaitForElement method, which also didn't work for me.

Waiting for element before clicking with WinAppDriver

[TestMethod]
public void UploadDocuments()
{
   var UploadButton = session.WaitForElement(By.XPath("//Button[@AutomationId='AddDocument']"), 60);
   UploadButton.Click();

   session.FindElementByXPath("//ToolbarWindow32[@AutomationId='1001']").SendKeys(Keys.Control + "a");
   session.FindElementByXPath("//ToolbarWindow32[@AutomationId='1001']").SendKeys(testFilesFolder);

   //session.FindElementByName("Open").Click();
}

The test usually crashes in the first line after it's finished with the ClassInitialize. So I would like to wait for the 'AddDocument' button to pop up before the test carries on.

If anyone has a solution I'd appreciate the help. Thanks!


Solution

  • You can implement wait funcionalities like this:

    public WindowsElement GetElementByAutomationID(string automationId, int timeOut = 10000)
    {
        WindowsElement element = null;
    
        var wait = new DefaultWait<WindowsDriver<WindowsElement>>(Driver)
        {
            Timeout = TimeSpan.FromMilliseconds(timeOut),
            Message = $"Element with automationId \"{automationId}\" not found."
        };
    
        wait.IgnoreExceptionTypes(typeof(WebDriverException));
    
        try
        {
            wait.Until(Driver =>
            {
                element = Driver.FindElementByAccessibilityId(automationId);
                return element != null;
            });
        }
        catch (WebDriverTimeoutException ex)
        {
            LogSearchError(ex, automationId);
            Assert.Fail(ex.Message);
        }
    
        return element;
    }
    

    Your problem seems to be a appium-dotnet-driver issue. See these issues on github about this: https://github.com/Microsoft/WinAppDriver/issues/329

    https://github.com/appium/appium-dotnet-driver/issues/225