等待元素,然后单击WinAppDriver [英] Waiting for element before clicking with WinAppDriver

查看:284
本文介绍了等待元素,然后单击WinAppDriver的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了这样一个小问题,但是我很难让我的代码在继续前进之前正确地等待一个对象.

I have such a trivial issue but I am having a hard time getting my code to properly wait for an object before moving on.

我为驱动程序设置了以下配置

I have the following config set for my driver

session.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(60);

我期望这意味着它将等待至少60秒,然后抛出与元素标识相关的错误,例如

I was expecting this to mean that it would wait a minimum of 60 seconds before throwing errors related to element identification such as

Message: System.InvalidOperationException : An element could not be located on the page using the given search parameters.

但是事实并非如此.尝试调用以下命令时,出现2秒左右的错误.

However this is not the case. I get the error around 2 seconds in when trying to call the following command.

WindowsElement btn = session.FindElementByXPath("//Button[@Name='NEXT']");
btn.Click();

该错误抛出在我仅定义按钮属性的行上,而不是实际的Click()方法上.我没有正确传递元素属性吗?为什么按钮的实例化也会对其进行搜索?

The error gets thrown on the line where I am just defining the buttons properties and not on the actual Click() method. Am I not passing the elements properties correctly? Why would the instantiation of the button also do the searching of it?

推荐答案

有一个未解决的问题在winappdriver github上.看看对此的评论.这似乎是一个Appium问题.我不知道这个问题的状态.

There it a open issue on the winappdriver github. Take a look at this comment about it. It seems to be a Appium issue. I have no idea about the status of this issue.

基本上,这意味着您将不得不采用解决方法.使用Thread.Sleep(/*milliseconds*/)坏主意.

Basically, this means you will have to resort to a workaround. Using Thread.Sleep(/*milliseconds*/) is a bad idea.

我在函数中实现了while循环,以通过自动化ID来获得控件,如下所示:

I implemented a while loop in a function to get a control by Automation ID like this:

    /// <summary>
    /// Gets a UI element based on a AutomationId.
    /// </summary>
    /// <param name="automationId">The AutomationId is a unique value that can be found with UI inspector tools.</param>
    /// <param name="controlName">The name of the UI element.</param>
    /// <param name="timeOut">TimeOut in milliseconds</param>
    /// <returns></returns>
    protected WindowsElement GetElement(string automationId, string controlName, int timeOut = 10000)
    {
        bool iterate = true;
        WindowsElement control = null;
        _elementTimeOut = TimeSpan.FromMilliseconds(timeOut);
        timer.Start();

        while (timer.Elapsed <= _elementTimeOut && iterate == true)
        {
            try
            {
                control = Driver.FindElementByAccessibilityId(automationId);
                iterate = false;
            }
            catch (WebDriverException ex)
            {
                LogSearchError(ex, automationId, controlName);
            }
        }

        timer.Stop();
        Assert.IsFalse(timer.Elapsed > _elementTimeOut, "Timeout Elapsed, element not found.");
        timer.Reset();

        return control;
    }

Thread.Sleep()相比,使用循环具有一些优点,它比简单地阻止代码执行更为灵活,并且您还有更多选择.

Using a loop has some advantages versus Thread.Sleep(), it's more flexible and you have much more options than simply blocking the code execution.

一些优点:

  • 您的测试脚本将继续执行:假设您的脚本在被测应用程序继续运行的过程中暂停了5秒钟.您的脚本可能想知道的那5秒内可能会发生很多事情.但这不能,因为如果使用"Thread.Sleep()",则会阻止代码执行.
  • 动态等待:一个while循环将迭代直到满足条件.这使您的脚本在满足此条件后立即继续测试,从而使脚本运行得更快.例如.您正在等待页面加载. Thread.Sleep(5000) 假设 可以继续,而循环 知道 则可以继续测试.
  • 使用计时器/超时"组合,您可以检查操作花费了多长时间(例如,保存了一些修改),并且如果花费的时间超过了超时,则知道继续操作是不正确的.

或者,此代码也将正常工作:

Alternately, this code will work just as well:

protected WindowsElement GetElement(string automationId, string propertyName, 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, propertyName);
        Assert.Fail(ex.Message);
    }

    return element;
}

以上代码只会抛出WebDriverTimeoutException,而不是连续抛出NoSuchElementException.它不使用while循环,但是我怀疑wait.Until(...)在做类似的事情,因为WinAppDriver每500ms轮询一次gui(请参见DefaultWait对象上的PollingInterval属性.

Above code will only throw a WebDriverTimeoutException instead of continuously throwing NoSuchElementException. It does not use a while loop, but I suspect wait.Until(...) is doing something similar, since WinAppDriver polls the gui every 500ms (see the PollingInterval property on the DefaultWait object.

这篇关于等待元素,然后单击WinAppDriver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆