1

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!

alisheikh
  • 89
  • 2
  • 10

1 Answers1

4

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

PixelPlex
  • 749
  • 5
  • 21
  • The answer did not work at this time. If you change `wait.IgnoreExceptionTypes(typeof(WebDriverException));` to `wait.IgnoreExceptionTypes(typeof(InvalidOperationException));` your wait timeout will function again. Reason is, that when calling `FindElementByAccessibilityId` you'll get `InvalidOperationException` fired when element is not found and **NOT** `WebDriverException`. – krs Aug 24 '20 at 14:29
  • @krs thx for this update. All I know is that it used to work at the time of writing that answer. - Doing a assumption here - perhaps this was changed in more recent versions of the selenium framework? – PixelPlex Sep 04 '20 at 06:45
  • @PixelPlex For me, when using either exception type - WebDriverException or InvalidOperationException, the function immediately returns the error "An element could not be located on the page using the given search parameters" and doesn't wait for the timeout – cw84 Sep 30 '21 at 10:28