c# - 如果 Element 不可见,则继续方法
问题描述
我正在使用 C#/Selenium 测试 UI,并且有一个数据输入部分,然后是一个结果窗口。要么返回结果,要么不返回结果。我正在测试这两种情况
我为此测试创建了一种方法,如下所示。这可用于测试元素是否存在的是/否场景......
public bool HasResults()
{
IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
if (yesResultElement.Count > 0)
{
return true;
}
IList<IWebElement> noResultElement = _driver.FindElements(noResults);
if (noResultElement.Count > 0)
{
return false;
}
throw new Exception("Could not determine if there were results");
}
问题是,当我测试“noResultElement”时,此方法会挂起并超时,因为它找不到“yesResultElement”。
我尝试在第一个 IF 语句周围添加一个 try/catch
public bool HasResults()
{
try
{
IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
if (yesResultElement.Count > 0)
{
return true;
}
}
catch
{
Console.WriteLine("element does not exist");
}
IList<IWebElement> noResultElement = _driver.FindElements(noResults);
if (noResultElement.Count > 0){
return false;
}
throw new Exception("Could not determine if there were results");
}
这解决了问题,但它也将 20 秒的测试变成了 > 1 分钟(由于测试文件中指定了隐式等待)
除了将其拆分为 2 种方法之外,还有更好的方法来处理这个问题吗?如果 yesResultElement 不存在,请忽略该 IF 语句并转到下一个,这就是我想要的。
测试看起来像这样
[TestMethod]
public void NoRecordsFoundTest()
{
// Tests whether no records are found when that is the expected outcome
var searchPage = new SearchPage(driver);
var firstTest = testData.First();
searchPage.EnterSearchInfo(firstTest);
var result = searchPage.HasResults();
try
{
result.Should().BeFalse();
log.Debug("The No Records Found Test Passed");
}
catch (AssertFailedException ex)
{
log.Debug("The No Records Found Test Failed",ex);
Assert.Fail();
}
}
[TestMethod]
public void RecordsFoundTest()
{
// Tests whether records are found when that is the expected outcome
var searchPage = new SearchPage(driver);
var firstTest = testData.Skip(1).First();
searchPage.EnterSearchInfo(firstTest);
var result = searchPage.HasResults();
try
{
result.Should().BeTrue();
log.Debug("The Records Found Test Passed");
}
catch (AssertFailedException ex)
{
log.Debug("The Records Found Test Failed", ex);
Assert.Fail();
}
}
不确定其相关但测试数据是从 JSON 文件加载并传递到 EnterSearchInfo() 方法。
此外,UI 中的一个小故障是即使返回了结果,noResultElement 也会在一瞬间出现,然后消失。
解决方案
您可以暂时将隐式等待超时设置为某个较小的值,反复尝试查找您的元素,等待至少找到一个组(使用OpenQA.Selenium.Support.UI.WebDriverWait
),然后根据找到的组返回一个布尔值。
像这样的扩展方法可能会有所帮助:
public static class WebDriverExtensions
{
/// <summary>
/// Executes the specified `action` with `ImplicitWait` set to the specified `timeout`.
/// </summary>
/// <typeparam name="T">The action return type.</typeparam>
/// <param name="b">The WebDriver instance.</param>
/// <param name="timeout">
/// The duration that WebDriver should implicitly wait until it gives up on trying to
/// find an element.
/// </param>
/// <param name="action">
/// The action to execute with the special ImplicitWait setting.
/// </param>
/// <returns>The action result.</returns>
public static T WithImplicitWait<T>(this ChromeDriver b, TimeSpan timeout, Func<T> action)
{
ITimeouts timeouts = b.Manage().Timeouts();
TimeSpan oldImplicitWait = timeouts.ImplicitWait;
try
{
timeouts.ImplicitWait = timeout;
return action();
}
finally
{
timeouts.ImplicitWait = oldImplicitWait;
}
}
}
然后你会像这样使用它:
public bool HasResults()
{
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10))
{
Message = "Could not find neither 'yes' nor 'no' results."
};
var implicitTimeout = TimeSpan.FromMilliseconds(200);
string found =_driver.WithImplicitWait(implicitTimeout, () => wait.Until(b =>
{
IList<IWebElement> yesResultElement = _driver.FindElements(yesResults);
IList<IWebElement> noResultElement = _driver.FindElements(noResults);
if (yesResultElement.Count == 0 && noResultElement.Count == 0)
{
return null;
}
if (yesResultElement.Count > 0 && noResultElement.Count > 0)
{
return "both";
}
return yesResultElement.Count > 0 ? "yes" : "no";
}));
bool result = found switch
{
"yes" => true,
"no" => false,
_ => throw new Exception("Could not determine if there were results")
};
return result;
}
WebDriverWait.Until
将重复调用您的回调,直到它返回一个非空值,因此我们null
在没有找到任何组时返回。它将在(在这种情况下)10 秒后放弃并失败并显示指定的错误消息。
推荐阅读
- php - 填充的数组返回空白
- android - 从字符串到浮动 android studio ESP32 蓝牙连接
- html - Atom 给我错误找不到模块“editorconfig”
- r - 在 Rmarkdown ioslides 中对齐和调整地图视图窗口的大小
- javascript - 如何将 Laravel 从 Localhost 更改为 live ip 地址?
- java - 将语音识别空白放置在 Fragment 中,然后从 MainActivity 应用程序崩溃中调用
- android - 任何人都可以获取我的数据库引用并在 firebase 数据库中对其进行编辑
- excel - Excel VBA突出显示行和列与2张匹配的单元格
- typescript - 使用打字稿如何定义一个返回相同对象的类型,每个值都有一个承诺
- java - 如何修复运行 Java API(Jetty + Java Service Wrapper)时没有可用的缓冲区空间?