Вот это открытый выпуск на github winappdriver. Взгляните на этот комментарий об этом. Кажется, это проблема с Appium. Я понятия не имею о статусе этой проблемы.
По сути, это означает, что вам придется прибегнуть к обходному пути. Использование Thread.Sleep(/*milliseconds*/)
- это плохая идея .
Я реализовал цикл while
в функции, чтобы получить элемент управления по идентификатору автоматизации, например:
/// <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()
, оно более гибкое и у вас гораздо больше возможностей, чем просто блокирование выполнения кода.
Несколько преимуществ:
- Ваш тестовый скрипт продолжает выполняться: представьте, что ваш скрипт останавливается на 5 секунд, пока тестируемое приложение продолжает работать. Многое может произойти за те 5 секунд, о которых ваш сценарий захочет узнать. Но это невозможно, потому что выполнение кода блокируется, если вы используете Thread.Sleep ().
- Динамическое ожидание: цикл while будет повторяться, пока не будет выполнено условие. Это заставляет ваш сценарий продолжать тестирование, как только будет выполнено это условие, и, следовательно, ваш скрипт будет работать быстрее. Например. Вы ждете загрузки страницы.
Thread.Sleep(5000)
будет предполагать нормально продолжать, пока цикл знает нормально продолжить тест.
- С помощью комбинированного таймера / тайм-аута вы можете проверить, сколько времени заняла операция (например, сохранить некоторые изменения), и, если она заняла больше времени, вы знаете, что продолжение не в порядке.
С другой стороны, этот код будет работать так же хорошо:
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 опрашивает графический интерфейс каждые 500 мс (см. Свойство PollingInterval
объекта DefaultWait
.