无法捕获某些元素的 WebDriverException

Can not catch WebDriverException for certain elements

我在页面对象中标识了以下元素..

public WindowsElement usernameField => _session.FindElementByAccessibilityId("UserName");
public WindowsElement passwordField => _session.FindElementByAccessibilityId("Password");
public WindowsElement menuButton => _session.FindElementByXPath("//Button[contains(@Name, 'Menu')]");

我按照以下步骤进行了测试..

WaitForObject(usernameField)
usernameField.SendKeys("...")

WaitForObject(passwordField)
passwordField.SendKeys("...")

ClickButton("Sign In");

WaitForObject(menuButton);
menuButton.Click();

下面是我的 WaitForObject 方法..

// Wait for an Object to be accessible
public void WaitForObject(WindowsElement element)
{
       var wait = new DefaultWait<WindowsDriver<WindowsElement>>(_session)
       {
           Timeout = TimeSpan.FromSeconds(10),
           PollingInterval = TimeSpan.FromSeconds(1)
       };

       wait.IgnoreExceptionTypes(typeof(WebDriverException));
       wait.IgnoreExceptionTypes(typeof(InvalidOperationException));
       wait.IgnoreExceptionTypes(typeof(StaleElementReferenceException));
       wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
       wait.IgnoreExceptionTypes(typeof(NotFoundException));

       WindowsElement waitElement = null;

       wait.Until(driver =>
       {
           waitElement = element;

           return waitElement != null && waitElement.Enabled && waitElement.Displayed;
       });
}

WaitForObject 方法非常适合 usernameField 和 passwordField 检查,但由于某些原因,它在传入 menuButton 时立即失败。我知道它正在正确检查 usernameField 和 passwordField,因为我包含了一些 Console.WriteLines() 以便在它检测到其中一个异常时打印出来。一旦它到达 menuButton,没有任何记录它只是立即失败并出现 WebDriverException

OpenQA.Selenium.WebDriverException : An element could not be located on the page using the given search parameters.

为什么它对 menuButton 的作用不同?我已经尝试过使用 while 循环捕获一般异常的其他方法,但是当它到达带有 WebDriverException 的这个元素时它仍然立即失败。

如果我在尝试检查元素之前使用 Thread.Sleep(10000),它可以正常工作并执行点击..

我正在使用 WinAppDriver / Appium 库。

您可以尝试使用正则表达式而不是按钮使用“*” 因为 inspect.exe 没有定义标签,即按钮。

否则继续使用名称定位器查找元素。

哦等等,抱歉,我仔细查看了您的代码。基本上发生的事情是因为方法参数要求类型本身,当 C# 将元素交给 WaitForObject 时,它会尝试在 "WindowsElement menuButton" 表达式交给 WaitForObject 时对其求值。通过更改 WaitForObject 方法以接受委托,您将推迟该评估,直到您进入等待状态。

您需要将 WaitForObject 更改为:

public void WaitForObject(Func<WindowsElement> element)

// Unchanged code here

wait.Until(driver =>
       {
           waitElement = element();

           return waitElement != null && waitElement.Enabled && waitElement.Displayed;
       });

然后这样称呼它: WaitForObject(() => menuButton); menuButton.Click();